Hey creators,
Today, we’re happy to announce the next steps for Luau’s New Type Solver Studio Beta! With this update, we’ll be moving out of Studio Beta for both the New Type Solver and Non-Strict by Default. In this release, we’re rolling out the New Type Solver to all users of nocheck and non-strict mode, alongside a new collection of Scripting workspace properties that you can configure to enable or disable the New Type Solver and to set the default typechecking mode for scripts.
Important: For Beta Testers
The Studio Beta feature for the New Type Solver will be removed in the first release of the new year on January 7th, 2026. If you have been using the New Type Solver in strict mode with the Studio Beta, please set the UseNewLuauTypeSolver property from Default to Enabled in your experience’s workspace to continue using it. All other users should be migrated automatically.
What is the New Type Solver?
The New Type Solver is a significant overhaul of the type system from the Luau team. It provides significant improvements to type inference, autocomplete, and typechecking, including:
- Read-only Table Properties: Inferred and annotated table properties can now be read-only, enhancing type safety.
- Better Type Refinements: The type system now tracks variable type changes dynamically and more intelligently, reducing instances where the logic of the program obviously contradicts the error
- Type Functions: Enables better inference for overloaded operators and table properties, increasing accuracy, and provides users a way to write highly expressive type signatures for code
- Singleton Type Improvements: Improved handling of singleton types reduces spurious warnings and the need for excessive casting.
- Relaxed Casting Rules: Casting rules are more permissive, reducing the need to cast through any when trying to cast to a specific type.
You can find a more detailed breakdown in our previous posts here and here.
Enabling and disabling the New Type Solver
With this update, we’re rolling out the New Type Solver automatically for the vast majority of Roblox users, namely everyone who is not currently using strict mode. If you’re in this category, you won’t need to do anything more to receive more accurate autocompletion results, and the error reporting from our new non-strict mode. If you run into any critical issues, you should report them readily to us to fix, but you can use our new setting, UseNewLuauTypeSolver, on a per-project basis to opt out of or back into the New Type Solver.
Setting this property to Enabled will mean that every person working on your experience will be using the New Type Solver while editing that place. With this on, the New Type Solver will take over powering autocomplete, hover type, and script analysis warnings for the whole project.
If you’re currently a user of the type system’s strict mode, we know that there are still a number of issues preventing existing projects from adopting the New Type Solver, as well as some intentional work that creators will need to do to fix real type errors that went uncaught because of the limitations of the old system. We’ll be working hard into 2026 polishing the New Type Solver and fixing these bugs, but we also wanted to provide a path for creators to adopt the new system at their own pace. So, if your project contains strict mode scripts today, you’ll be opted out of the New Type Solver by default, but you can enable it with this setting.
Note: We will retain this property in Studio for at least one year and until we’ve entirely sunset the old Luau type inference engine. We’re committed to delivering a high-quality developer experience for Luau. Part of that is giving you time to migrate at your own pace.
Setting the default typechecking mode
This Scripting configuration category also includes an oft-requested option to set the default typechecking mode for scripts on a per-experience basis. Historically, every script defaulted to no typechecking and creators could provide script directives like --!strict and --!nonstrict to set the mode in each file. With this update, script directives continue to work as before, but the default mode will be determined by LuauTypeCheckMode. As we roll out the New Type Solver, we’ll be setting Nonstrict as the initial value of this property in Roblox-provided templates to provide all creators a better developer experience out of the box in their new projects. This setting will continue to exist in some form in perpetuity as we believe that individual creators are best able to determine the typechecking mode best suited for themselves, their workloads, and their teams.
A New Nonstrict Mode for Luau
As the long-standing persistence of the Non-Strict by Default beta feature surely suggests, nonstrict mode has always been something we’ve wanted to be able to turn on by default for all Luau scripts. We believe this to be a very ambitious goal because we recognize that a significant portion of creators (and indeed of programmers in general) are not necessarily interested in some of the labor involved with static typing (like annotating code). Toward that end, we want nonstrict mode to give clear, useful developer feedback during editing without requiring annotations and without requiring the creator to understand type systems.
Instead of varying the type inference rules based on mode, we’ve written a new implementation with one shared type inference pass between each mode with separate error reporting implementations. These error reporters, called typecheckers, define sets of rules for what script analysis warnings get produced. Our current set of rules for the new nonstrict mode, based on feedback collected from the beta, are focused on two flavors of warning:
- simple lint-style warnings like unknown symbols, and
- circumstances where we can prove that the code will behave nonsensically at runtime.
As an example of the simpler lint-style warnings, the new nonstrict mode will catch and report unknown global variables, meaning that in circumstances like writing a typo of a variable name, you’ll encounter your beloved (behated?) red squiggles:
local dog = { name = "molly", age = 13 }
local cat = { name = "athena", age = 2 }
function pet(animal)
print(`pets for {animal.name}`)
end
pet(dig) -- oops! unknown global: dig
pet(cat)
Further, the new nonstrict mode can help identify instances where the code you’ve written will error at runtime, and provide context for that (though we’re definitely interested in improving the error messages a lot in these cases). As a simple, but contrived example, consider:
function foo(x)
math.abs(x)
string.lower(x)
end
We will report a warning for this function in nonstrict mode because there is no possible way to call the function without causing a runtime error. If we pass anything other than a number, math.abs will fail, and if we pass anything other than a string, string.lower will fail.
By contrast, the following program will not warn because it might work:
function bar(x)
if math.random(2) == 1 then
math.abs(x)
else
string.lower(x)
end
end
The new nonstrict mode remains very permissive right now as a foundation for continued work, but serves as a basis for what we can comfortably enable for everyone by default. We intend to continue iterating on the classes of errors reported by nonstrict mode, and polishing the errors themselves to be as readily understandable as possible. If there’s other classes of warnings you feel strongly are missing, please submit feature requests for consideration!
Known Issues and Next Steps
We are committed to polishing the New Type Solver, including continuing to fix bugs and build further on the new architecture we’ve set up. In the meantime, we’re committing to keep the old type inference engine available through 2026 to give everyone time to migrate at a reasonable pace.
We are actively working on several known issues, particularly for strict mode:
- Error Message Quality: In some cases, the New Type Solver can generate types and error messages that are larger and more verbose, or otherwise less clear than the old system. We are working to improve this, but would love feedback on major pain points.
- Performance: The New Type Solver is still slower than we’d like in some cases, which can sometimes lead to excessive memory usage in Roblox Studio. We are continuing to drive performance and memory improvements that should make the new type inference system more performant than the old type system. If you run into any issues, providing a reproduction path is a huge help!
- Correctness Bugs: While we’ve resolved most “blocked type” or “inference failed” errors, some cases may remain. We’re also aware of a number of places where strict mode type-checking is currently too strict, and are working to address them. In general, if you see behavior that doesn’t make sense to you, don’t assume it’s intended, please file a bug!
Note: None of these issues can affect your experience in production, the type system only runs at edit time in Roblox Studio.
FAQ
What happens if I do nothing?
- If you use nocheck or non-strict mode for all of your scripts, you will be automatically moved to the New Type Solver with nonstrict enabled. If you use strict mode, you will remain on the old solver by default, but can opt-in via Workspace Properties.
What if I was using the “Non-Strict by Default” beta?
- This is now the default behavior! We are also setting “Nonstrict” as the initial value for LuauTypeCheckMode in all new Roblox templates. If your preference differs, you can set the value that suits you and your project best!
What if I find a bug or have performance problems?
- Please report them to us via the DevForum bugs report! A consistent reproduction file is the fastest way to help us fix the issue. If you run into a critical issue, you can use the UseNewLuauTypeSolver property to opt out of the new solver for that project.
Resources
If you would like to know more about the Luau’s type inference engine, or hey — if you’re just starting out and want to know more about Luau — be sure to check out the following links!


