[FREE] Nestify - 130 Lines, Dialects, Inheritance & Reactive Luau Framework

[FREE] Nestify - 130 Lines, Dialects, Inheritance & Reactive Luau Framework

logo

Nestify is a super-lightweight Luau framework (~130-145 lines depending on dialect) designed for declarative, inheritable, and reactive UI/instance development. It’s highly flexible thanks to dialects, which let you choose different syntax options depending on your style or project needs.

Features

  • :feather: Ultra-lightweight: ~130–145 lines of pure Luau
  • :writing_hand: Multiple dialects: switch syntax styles easily
  • :chains: Inheritance & declarative: define components with reusable properties
  • :high_voltage: Reactive elements: workarounds included for dynamic updates
  • :printer: Has Free compiler (Hierarchy Saver): Automatically turn Instance into Framework tree

Why Nestify + Hierarchy Saver

If you use Hierarchy Saver, you can compile Roblox Instances dirrectly into Nestify code, making it easier to manage, share, and maintain your projects. Nestify acts as a free framework, and Hierarchy Saver acts as its free compiler, giving you a complete lightweight workflow.

Installation

  1. Download Nestify from GitHub: GitHub - YarikSuperpro/Nestify
  2. Optionally, use Hierarchy Saver to serialize your components into Nestify code.

Formatting options:

Inspired by Hierarchy Builder

Major dialects code samples

Major dialects code samples

Lets create with decal in each to see how they differ.
Notice that dialects with [Children = {}]:white_check_mark: wrap children inside [Chlidren] = {}

Default (original) :cross_mark_button: :cross_mark_button::

local new = require("@self./Nestify")

local Part = new {Class = "Part";
	Name = "Hello";
	{Class = "Decal";
		Face = Enum.NormalId.Top;
		Texture = "rbxasset://textures/SpawnLocation.png";
	}
}

Default new(Class,{}) :cross_mark_button: :white_check_mark:

local new = require("@self./Nestify")

local Part = new("Part", {
	Name = "Hello";
	new("Decal",{
		Face = Enum.NormalId.Top;
		Texture = "rbxasset://textures/SpawnLocation.png";
	})
})

Fusion like syntax :white_check_mark: :white_check_mark:

local Nestify = require("@self./Nestify")
local new = Nestify.Nestify
local Children = Nestify.Children

local Part = new "Part" {
	Name = "Hello";
	[Children] = {
		new "Decal" {
			Face = Enum.NormalId.Top;
			Texture = "rbxasset://textures/SpawnLocation.png";
		}
	}
}

Example Usage

Module
local RunService = game:GetService("RunService")

local ListRGB:{GuiObject} = {}

RunService.PreRender:Connect(function():()
	local color:Color3 = Color3.fromHSV(time()%1,1,1)
	for i,v in ListRGB do
		v.BackgroundColor3 = color
	end
end)

local module = {
	rgb = {
		_init = function(self:GuiObject):()
			table.insert(ListRGB,self)
		end;
	}
}

return module

local Players = game:GetService("Players")

local new = require("@self/Nestify")
local Components = require("@self/Components")

local screen = Instance.new("ScreenGui",Players.LocalPlayer:WaitForChild("PlayerGui"))

local Part = new {Class = "TextButton",
	_base = Components.rgb;
	Text = "Click Me",
	Size = UDim2.new(0, 100, 0, 50),
	_run = function(self:TextButton):()
		self.Activated:Connect(function():()
			print("Im clicked")
		end)
	end
}
Part.Parent=screen

Notes

  • Nestify is intentionally minimal, giving you full control without overhead.
  • Reactiveness requires workarounds by design, letting you learn and control updates manually.

Tutorial (in depth)

Click to expand

Nestify is built to be based on macros for setting things up

Here is an order in which macros/properties execute:

Properties:

Allows you to set properties.
Note that “Class” is mandatory (depending on dialect) unless you write a _base macro.

local Part = new {Class = "Part";
	Name = "Hello";
	Parent = workspace;
}

Macros:

_exec

Allows you to execute instance methods and has multiple syntax options:

Option 1:

{
	_exec = {
		SetAttribute = {
			Hello = true;
		};
		AddTag = {"Bye"};
	}
}

Option 2:

{
	_exec = {
		SetAttribute = {
			{"Hello";true;}
		};
		AddTag = {{"Bye"}};
	}
}

_base

Inheretance/commonly used patterns/initiation.

Allows you to create a linked chain of inheritance and abstract away initiation from the declarative part.
Note that this does not have a “Class” for base.
Note how _base can fit other macros inside itself, such as _exec, _run, other _base, and _init.

local base1:new.Base = {
	Name = "True";
	_run = function(self:Instance):()
		print("My name is",self.Name)
	end;
}
local Base2:new.Base = {
	Archivable = true;
	_base = base1;
}
local Base3:new.Base = {
	Parent = workspace;
	_base = Base2;
}

local Part = new {Class = "Part";
	_base = Base3;
}

_run

Initiator/Callback runs during instance creation and can yield an algorithm if the function you pass does yield. Use _init if you want to avoid this behavior.
Callback is optional; if you return an instance, it replaces the original.
Returns: self (instance we create), id (order can be useful with the _count macro; otherwise, it’s always 1)

No callback:

local Part = new {Class = "Part";
	_run = function(self:Part,id:number):()
		self.Touched:Connect(function()
			print("Ouch")
		end)
	end;
}

Callback:

Replaces our “Folder” with a “Part”

local Part = new {Class = "Folder";
	_run = function(self:Folder,id:number):Part
		self:Destroy()
		local heheh = Instance.new("Part")
		return heheh
	end;
}

_init

Exactly like _run but runs inside a task.defer (there so doesn’t yield) and doesn’t have a callback option.

local Part = new {Class = "Part";
	_init = function(self:Part,id:number):()
		print("Initialized")
	end;
}

_count

Pretty interesting macro, although it doesn’t really have too many uses.
It allows you to return multiple instances, and for each of them, the _init and _run second argument “id” will be returned depending on the number of instances.

local Part1,Part2,Part3 = new {Class = "Part";
	_count = 3;
	_run = function(self:Part,id:number):()
		print("My number:",id)
	end;
}

Links

4 Likes

First framework to come with a compiler pretty sure
nowayomggg

dude, roblox already compiles luau, I dont know why you need a compiler, we arent building visual studio on roblox

also: " The last reply to this topic was 67 days ago. Your reply will bump the topic to the top of its list and notify anyone previously involved in the conversation.

Are you sure you want to continue this old conversation?"

67??

Did you really dig through old posts just to say that because I criticized React? Very low of you.

The abandoned React comment aside, I made Nestify for a unified syntax for Fusion like users; my current focus is a pure Luau compiler in Hierarchy Saver.

And yeah… 67 days?? Peak thinking capabilities, bro. :skull:

Less lines of code does not equate to being lightweight. You can have small codebases do heavy things.

It doesn’t look good in the codebase either – in an attempt to use less code, the code became very unreadable; I have no idea what I’m looking at when just glancing at the source on GitHub.

This just isn’t true, you seem to not understand what “reactive” means. In order for a state to react to another, you need state to directly create a result. Just running a function does not mean it’s reactive.

This is usually bad practice. Assets should be stored as assets, not code.


From what I can tell, you seem to like the idea of Fusion, but you don’t actually understand how it works, or what it’s for. Fusion’s goal is to have state-based reactivity and simple syntax for a UI framework. You have a somewhat similar goal, but you’re going the wrong direction.

2 Likes

Cool take, except my compiler literally exists for fast iteration, not as a religion.
Make UI in Studio → press button → get clean Luau.
Sorry if my workflow being faster than yours personally offends you.

Also, calling it “bad practice” while Fusion requires a novella worth of code to make a button is wild.

Bro, you’re acting like I tried to reinvent Fusion.
I wasn’t chasing ‘reactivity,’ I was chasing speed.
Fusion is cute for people who want to write JSX fanfiction in Luau.
I wanted something that doesn’t tank performance on contact.

Fusion: 2000+ lines, wrapper structs, abstractions on abstractions.
Mine: 130 lines because I skip the bloat.
If I can do same thing with 90% fewer lines, that’s literally the definition of lightweight.
Math doesn’t lie.


The project is abandoned anyway - I moved to raw Luau because it’s faster.
You like abstractions, I like performance.
Different goals, different tools. No need to convert me to the Church of Fusion.

Optimization is the goal; everything else is noise.

You completely mistook my intentions here, and you still don’t understand what I’m saying.

This is peak DevForum, folks.

7 Likes

If I misunderstood, then clarify.
I’m not accepting vague “you don’t get it” statements - that’s not an argument, that’s dogging the truth.

If you have an actual point, spell it out.
If not, just wave the white flag and move on.
For now i’ll interpret your vague answer as surrender.

This tool was inspired by my own now archived tool (no thanks to bad advertisement practices of the OP), which was intended to be used in environments where no direct asset loading was possible. It came off as a solution for the challenge of making a Roblox game purely with code, with every default core script available being removed too. And as an additional bonus: fix some asynchronous behaviors.

Existing frameworks were simply too much for this, as they attached some unnecessary stuff without the option to remove it. It solved the problem via optionally adding reactive behaviors via the _init

It is meant to solve the problem of often verbose syntax via the default property setting:

local root = Instance.new("Model")
root.Name = "Root"
root.Parent = workspace

local part = Instance.new("Part")
part.Name = "SomeName"
part.Parent = root

--imagine this for 100 instances

Instead to:

local hierarchyBuilder = require(".")

hierarchyBuilder{
   Type = "Model";
   Name = "Root";
   Parent = workspace;

   {
      Type = "Part";
      Name = "SomeName";
   };
}

It was convenient to store these tables in module scripts and then just use a centralized buildInstance function. Later on I expanded the tool a bit to include other capabilities like convenient attribute/tag setting as well as some convenience properties to make reactive behaviors in _init a bit easier to write (good example: _base which introduced inheritance)

Sadly, OP took this tool as a full-on replacement for any kind of instance framework there is simply for being very small in code size as well as a very lightweight result (no extra tables/behaviors attached unless absolutely directed to). And created his own variation of my tool in hopes of making it look like a full-on framework

2 Likes

Correct but also incorrect (kinda)
Hierarchy Saver (plugin-compiler) came off first and during development evolved into a pure raw Luau code compiler for generating instances without any bloat. The original idea was to have it structured purely around Nestify/Hierarchy Builder, but during mid-development I decided that plugin has much better potential, so it became two things at once.
To not have a waste, I decided to release Nestify as well and kept both, and to have compatibility with other frameworks, I added some options for formatting. Currently, the main priority of Hierarchy Saver is raw luau, and I keep the Nestify compile option for frameworks.