Major releases went out for a large set of the symbolic stack, including:
ModelingToolkit v11
Symbolics v7
SymbolicUtils v4
This is a massive transformation of the symbolic ecosystem in Julia, with a focus on improving type-stability and performance, as well as setting the stage for future array programming capabilities. Major props to Aayush Sabharwal for leading much of the development on this release. With this, we have a lot to talk about and share. Some of this is a difficult discussion which we want to be transparent about, so please read through the entire post.
One note on timing before we get into it. ModelingToolkit v11.0.0 was tagged on December 11, 2025, and most of this post was written around that release, but we held onto it while the community feedback threads on the library split and licensing ran their course. Publishing a seven month old announcement as though it were news seemed worse than publishing it with the benefit of hindsight, so the latter is what this is. The series is now at ModelingToolkit v11.36, ModelingToolkitBase v1.57, Symbolics v7.33 and SymbolicUtils v4.40, and wherever something described below turned out differently than we expected, the text says so.
One significant item to address with this update is the licensing associated with ModelingToolkit.jl. Starting with version 11, ModelingToolkit.jl is structured in a way where some of its dependencies have an AGPL license. In short (and will be elaborated on later), ModelingToolkit.jl and SymbolicUtils.jl now include an extendable pass system for the compiler, meaning that additional compiler passes can be added into the system through downstream dependencies. This is a powerful feature that allows for more extensibility and customization of the symbolic transformation process. This is something that was attempted from the start, which is why the StructuralTransformation.jl subpackage/submodule was always shipped with ModelingToolkit.jl, but the pass system was never modular enough to allow for external extensions, now it does.
ModelingToolkitBase.jl is a new, MIT-licensed package with no Julia AGPL dependencies that contains most of the core functionality of ModelingToolkit.jl. This for example includes the utilities for building Systems, generating code for ODEs, SDEs, etc., and the main symbolic compiler pipeline. ModelingToolkitBase.jl is thus a fully functional symbolic modeling compiler which can take symbolic descriptions of systems and generate performant Julia code for them as-is.
What has changed is that the symbolic transformation components which are primarily used by acausal DAE models, for example index reduction, structural singularity removal, and the advanced tearing and alias elimination passes, have been moved into two packages, StateSelection.jl and ModelingToolkitTearing.jl, which both live in a separate repository (https://github.com/JuliaComputing/StateSelection.jl) licensed under AGPL and managed by JuliaHub. We note that a basic tearing pass is still included in MTKBase under an MIT license, so simple acausal models, handling of observed equations, etc. will all still work under the fully MIT version, but continued work and expansion of the symbolic passes related to DAEs for new stability enhancements are included in the AGPL version.
As AGPL is an OSI-approved license, this package is open source and released as part of the General registry, meaning that ModelingToolkit.jl remains easy to install and use for open source projects. However, depending on how one uses ModelingToolkit, the AGPL license may have some additional requirements you must satisfy, so please review the license if you are considering using the full ModelingToolkit.jl library. For example, if you are redistributing ModelingToolkit.jl in a shipped binary or web service, then you need to ensure the licensing requirements of AGPL are satisfied. We again stress, however, that the MTK extension library license change only impacts the full ModelingToolkit.jl library that includes the symbolic transformation extension libraries for handling acausal models and high-index DAEs. If one only installs and uses ModelingToolkitBase.jl, then the underlying library is still MIT, and has the same permissiveness as ModelingToolkit v10.
This was a difficult decision to make, and the evolution of ModelingToolkit.jl shows many scars of previous failed attempts to do this correctly. We previously had StructuralTransformation.jl as a separate package back in the early days of ModelingToolkit.jl, but ultimately the developer burden of maintaining it separately was so high that it had almost killed the entire project. Because of this, we had always had to hold back on actively releasing some of the more advanced features into the ecosystem. Some of the coolest features and major advancements in acausal modeling, such as techniques for making large loops and arrays compile fast, specifically had to be omitted or kept separate in order to deal with licensing issues due to the commercial aspects for which they were developed. Many may recall the project JuliaSimCompiler.jl, which was a separate backend to ModelingToolkit.jl models that implemented many of these compiler passes. Ultimately, having to maintain two separate compilers means having 2 bad compilers: during the time frame of JuliaSimCompiler the issues list in both repositories grew enormously and the bug surface became very high due to divergences in compiler support. Once more, having this separate compiler almost killed the entire project due to the high maintenance burden.
Thus we had to spend some time to really think through how to do this effectively in a way that would be sustainable for the future of the project. Ultimately the issue is that, unlike what has occurred in the solver ecosystem, almost all of the funding that has been achieved for ModelingToolkit.jl throughout its entire lifespan has had both developer and government requirements for commercialization. While many may believe that the (US) government supports open source software development and would prefer for this software to be distributed as free under a permissive license, the reality is that government contracts and grants often have requirements for commercialization. For full transparency, ModelingToolkit.jl has required about 3 full-time expert/senior developers for the last 5 years, and the funding for this project has totaled around ~$250k (after overhead) of government grants directed to the non-commercial aspects of the project (we thank Bernt Lie for his early contributions via DigiWell and Chris Tessum for co-PIing on a related NSF grant). We additionally note that total donations to the project have been <$10k over the full 10 years.
As one may guess, 15 developer years for the top developers of the SciML space was not able to be sustained on that budget, and thus most of the shortfall was made up through commercial contracts and grants with commercial requirements, such as grants from DARPA and ARPA-E. However, these grants and contracts often have requirements for commercialization and thus items around ModelingToolkit.jl have repeatedly required to be removed from the grant scope due to reviewer feedback suggesting that these activities do not fall under the required commercialization scope. That is not to mention all of the lost funding due to this sustainability issue: in particular about $6 million of grants on the topic of improvements to ModelingToolkit.jl were denied this year. The repeated main reasoning has been the lack of measures addressing the commercialization sustainability requirements of the funding agencies, citing the fact that the liberal MIT license would allow competitors and large companies who do not contribute to the project to use all contributions to build a competing project (and this is something that has been seen).
Because of these requirements, we looked for a solution that satisfies all of the following criteria:
The core functionality of ModelingToolkit.jl, in particular the parts that are used by projects such as Catalyst.jl and SymBoltz.jl which are just developing and compiling ODEs, remains open source and permissively licensed. This includes enough of the symbolic compiler passes so that basic acausal models, handling of observed equations, etc. continues to work in the purely MIT licensed version.
There are sufficient protections in place for the JuliaHub developments in order to continue to secure both commercial and government funding for those full time on the project. In particular, this is the functionality around acausal modeling, high-index DAE handling, and large-scale model compilation optimizations.
The developer burden of maintaining the codebase remains manageable and does not lead to fragmentation of the symbolic compiler ecosystem.
We believe that this major infrastructure change satisfies all these requirements. ModelingToolkitBase.jl is a GPL-free core version that libraries such as Catalyst.jl and SymBoltz.jl can directly depend on, while the acausal modeling capabilities still work without any changes to user code by just doing using ModelingToolkit. The developer burden is manageable since there is now a single codebase for the symbolic compiler. Since AGPL is still an OSI-approved open source license, the code remains open source and available for use in open source projects without any issues. The packages are registered in the General registry which means that installation remains easy, and the source code is fully available for inspection, research, and contributions.
We are additionally excited to see what this pass system leads to. This infrastructure open up the possibility to slot in alternative implementations of tearing (in particular optimal tearing algorithms using SAT solvers which would be a fantastic PhD project), as well as other advanced symbolic transformations.
Ultimately, our goal is always to increase the sustainability of the Julia package ecosystem by bringing in as many developers into the space as possible. We have found over the years that selectively working with the commericial sector has vastly improved the number of open source developers when done right. For example, PumasAI has continued to fund some of the major contributors to Optim.jl, Makie.jl, Turing.jl, etc. to an extent that much of this only exists due to the effective commercialization of the nonlinear mixed effects fitting system being commercialized. As such, we similarly hope that this change will allow for more developers to be able to be in this symbolic-numeric computing space.
But we do realize this will have some implications to some users. Please feel free to reach out to me, Chris Rackauckas, via email directly if you want to discuss this in further detail.
Now to share all of the exciting benefits we get from this!
With this set of changes, for the first time SymbolicUtils.jl, Symbolics.jl, and ModelingToolkit.jl have fully type-stable pipelines. This means two major things:
All symbolic operations allocate less and are faster
Code associated with the symbolic computing stack now is more predictable for the Julia compiler, and thus precompilation actually works, largely fixing the "time to first X" associated with all symbolic operations that are precompiled.
This is a major change as Symbolics.jl and ModelingToolkit.jl have long been cited as two of the libraries which have the worst time-to-first-X issues in Julia due to the heavy use of dynamic typing in the symbolic computing stack. This has now been largely fixed by using a recursive sumtype representation. The exact solution is rather technical, see https://github.com/JuliaSymbolics/SymbolicUtils.jl/issues/737 for details. This allows us to marry the performance improvements of the advanced term representation with type-stability and all its associated performance benefits in SymbolicUtils.jl representation.
The effect on time-to-first-X is not subtle. Here are the first-call timings for the most common ModelingToolkit operations before and after the change, with the full @time output in the v11 release notes:
| Operation | Before | After | Speedup |
|---|---|---|---|
System constructor | 0.244 s | 0.00067 s | ~360x |
complete | 1.795 s | 0.0012 s | ~1500x |
TearingState constructor | 0.374 s | 0.0021 s | ~180x |
mtkcompile (first call) | 1.773 s | 0.0186 s | ~95x |
What makes those "before" numbers what they are is that they're 99%+ compilation, and a good chunk of that is recompilation. The old dynamic representation meant Julia had to recompile the compiler pipeline itself in every fresh session, so essentially none of it could be cached by precompilation no matter how many @compile_workload blocks we threw at it. Now that work happens once, in the package's precompile step, and the first call is basically just runtime. The exact numbers will of course depend on the system, whether index reduction is needed, whether there are array variables involved, and what else you have loaded, but the shape of it holds up.
Because the core aspects were now type-stable, changes were made to the parts on top of the representation, in particular the functions of Symbolics.jl and the compiler pipeline of ModelingToolkit.jl, to ensure that they also maintained type-stability. This has led to major performance improvements across the entire symbolic stack. But it also included some breaking changes to give type-stable routines by default. One example of this is that substitute(2x + 3y, Dict(x => 1, y => 2)) now returns a BasicSymbolic expression of a constant rather than the Int 8, because all substitutions now return symbolic expressions to maintain type-stability. This can be changed by using Symbolics.evaluate to get the evaluated result, or moving to other options like adding fold = Val(true).
There are still some functions being worked on to make them fully type-stable, for example the ODEProblem build function still has some dynamic typing in it that increases the time-to-first-ODE-solve a bit. However, we believe that all of the required breaking changes have been made, and thus we wanted to get this version out there, and future minor version releases in the v11 time frame will continue to improve type-stability, performance, and time-to-first-X based on this new foundation. Seven months later that has held up: there have been 36 minor releases since v11.0, all of them non-breaking, and a good fraction of them are this sort of incremental type-stability and allocation work.
Major props to Aayush Sabharwal for leading this effort.
One of the major issues with ModelingToolkit since its inception has been the speed of codegen for large repeated sets of equations, such as those stemming from PDEs. We have not fully solved this problem, but the major infrastructure changes give us all of the right tools to finally have a fully maintainable solution. In particular, SymbolicUtils.jl now fully supports array code during its code generation pathways. No scalarization is done at this level or Symbolics.jl.
Its code generation also allows for alternative plugin packages to add steps to the compilation. The new library SymbolicCompilerPasses.jl (AGPL, like the other JuliaHub-managed pass packages), is one such pass library that is being shipped that has the ability to ensure that array code is optimized, including doing things like using a bump allocator in order to achieve performance to pre-allocated code, using in-place mutating operators in the generated code. It will soon do things like automatically swap small operations, such as \ of 4x4 rotation matrices, to change them into static array operations. As such, it effectively transforms symbolic mathematical expressions into the kind of StaticArray.jl + specialized LinearSolve.jl + tensor contracted + etc. code that you would expect expert Julia users to write. On top of this, the library is scheduled to allow for Reactant.jl as a plugin (once integration issues are handled (https://github.com/EnzymeAD/Reactant.jl/issues/1864)), so that all of the automated parallelism / GPU features from Reactant are also available on Symbolics-generated code.
This is one of the alternative passes that are additionally scheduled to be turned on by default from the ModelingToolkit compiler when ready. The ModelingToolkit tearing passes still need to improve their rules around arrays to remove some scalarization, and this will happen in the v11 time frame as no breaking changes are required for that. When completed, the generated code for array expressions will be O(1) in code size and compilation time. This will solve a long-standing issue in the ModelingToolkit compiler, and approximately 60% of the work is now completed because the Symbolics code generation was one major aspect.
Of everything described in this post, this is the piece that has moved slowest since the release, and it would be misleading to leave the paragraph above sitting there without an update. As of ModelingToolkit v11.36, SymbolicCompilerPasses.jl is still not turned on by default from the ModelingToolkit compiler; it remains opt-in. The Reactant.jl integration is likewise still waiting on the upstream issue linked above, which is open at the time of writing. What has landed in the meantime is a steady stream of array handling work on the ModelingToolkit side: preserving arrays through flattened variable lookup, propagating array parameter assignments into SCC subsystems, dropping scalarization out of observed-function codegen. So the foundation is real and is being built on. But if you came here specifically for O(1) array codegen on by default, that is still ahead of us rather than behind us.
We note for avid users that MethodOfLines.jl will need a substantial change in order to use array expressions in order for our PDE discretizers to benefit from these improvements, and NeuralPDE.jl's codegen will need a rewrite to use this all. So there is a lot of work to still be done to see it throughout the ecosystem, but the first major steps are complete. Neither of those rewrites has happened yet, and both are good places for new contributors to have an outsized impact.
This section changed more than any other between when it was drafted and when it was published. I could have silently rewritten it, but the difference between what we were going to say and what happened is instructive enough that it seems better to show both.
The plan was to announce that ModelingToolkitStandardLibrary.jl would soon be deprecated in favor of the Dyad standard libraries, on the grounds that it had fallen behind, that nobody was actively maintaining it, and that an alternative existed which subsumed its functionality.
Then the library got maintainers again. In the seven months since v11.0 was tagged it has taken over 100 commits and a steady stream of releases, sitting at v2.29.5 as I write this, with work from Fredrik Bagge Carlson, Aayush Sabharwal, Sebastian Micluța-Câmpeanu and others. And it is not busywork: a large share of it is the sort of thing the deprecation notice was complaining about the absence of: fixing rotational mechanics initialization and torque balance, repairing thermal and magnetic component tests, getting SISO initialization exercised through ODEProblem, tracking the v11 compatibility floors. Meanwhile the Dyad component libraries we were going to point people at have not seen a public push since mid-2025.
So the deprecation is called off. ModelingToolkitStandardLibrary.jl is supported and you should keep using it. I have left the original reasoning below, partly because it was a fair description of where the library sat at the end of 2025, and partly because it is a nice demonstration of how fast "this is unmaintained" stops being true once two or three people decide otherwise. If you use this library, the maintainers would still be happy to have the help.
This was due to focusing more of the ModelingToolkit.jl maintenance team on a smaller set of codebases in order to ensure that we can grow in a more sustainable manner. In particular, the ModelingToolkitStandardLibrary.jl's deprecation is due to simply falling behind. Not only had no one been actively maintaining this library, but an alternative open source library has come up which subsumes all of its functionality while fixing many of its remaining bugs. This is the Dyad standard library. The Dyad standard library's repositories are split rather than in one repository, for example ElectricalComponents.jl is for the electrical components, while TranslationalComponents.jl is for the translational components. In addition, they include many improvements and designs made by Michael Tiller, one of the leading figures in acausal modeling and Modelica world for having written many of its foundational books and training materials. Thus they are simply a more solid version of these standard libraries, have more guarantees about accuracy and numerical stability, and thus are what should be used instead.
We should note that while Dyad is a commercial product that requires a license for commercial use, its standard libraries (i.e. the ones matching the ModelingToolkitStandardLibrary) are open source and licensed with the liberal BSD-3 license. Dyad by design generates ModelingToolkit.jl code as part of its compilation process, meaning that these standard libraries include a Julia package with ModelingToolkit versions of every component that can be used without installing Dyad. As such, these component libraries serve as a fully open source alternative to everything in the ModelingToolkitStandardLibrary.jl, but have lots of testing in the real world, and many thoughtful design decisions from some of the industry's best.
All of that is still accurate, and the Dyad component libraries are well worth evaluating on their own merits, particularly if you want components whose semantics trace back to the Modelica Standard Library. It was only the conclusion we drew that turned out to be wrong. Having two maintained options beats having one of them deprecated. We do still owe better documentation and discoverability for people who want to use the Dyad component libraries from plain ModelingToolkit without Dyad itself.
@mtkmodel Macro and Focusing the Development Effort of ModelingToolkit.jl as a CompilerUnlike the standard library above, this one went through as planned, and it got the better of the two outcomes we floated: @mtkmodel is deprecated out of ModelingToolkit v11, but it was spun out rather than killed. It now lives in SciCompDSL.jl, MIT licensed and currently at v1.0.1, developed in the ModelingToolkit monorepo under lib/SciCompDSL. It has had enough work to keep building systems on v11, so existing @mtkmodel code still runs. You add SciCompDSL to your project and using SciCompDSL instead of picking the macro up from ModelingToolkit. It won't get further maintenance from the core ModelingToolkit developers, but it is open to contribution, and having it as its own package means somebody can take it over without needing commit rights to the compiler. The rest of this section is why we went that way.
The @mtkmodel macro was designed as a Modelica-like syntax for which one can use ModelingToolkit.jl. While some effort was put into it at the early stages, it ultimately has lacked much development for around the last year and a half. It is generally rather buggy and leads to more difficult debugging. Thus for around the last year, for most issues we have suggested that users rewrite their code to not use the macro whenever sharing bug reports. We are finally making the decision to fully deprecate the @mtkmodel macro. The reasoning is simply that there are almost no maintainers, so while it does something interesting, it is not at a state which gives ModelingToolkit.jl a good look, while it does not add a major benefit for the maintenance time it takes, and thus should not be what people see in the first tutorial.
Because of this, all of the documentation will be updated to instead use the direct ModelingToolkit.jl form. We believe that this accomplishes a few goals. Firstly, it decreases the feature surface, making it easier to have a less buggy project and thus simply a better user experience. It also more clearly brings users into the "core" usage of ModelingToolkit as a compiler, where the direct interface has always been more flexible for many use cases like building libraries and things which are not related specifically to acausal modeling of DAEs (for example, @mtkmodel still does not even support SDEs). This lets the ModelingToolkit.jl team focus on what ModelingToolkit does best, namely, it's a symbolic representation for models and a compiler to fast and stable numerical simulations.
That does not mean that we do not like DSLs on ModelingToolkit, oh not at all! Instead this is making @mtkmodel no longer a privileged DSL of the project. For example, SymBoltz.jl and Catalyst.jl are two great DSLs built on ModelingToolkit.jl, just as separate packages. Spinning @mtkmodel out into SciCompDSL.jl puts it on that same footing. The open call for new folks to come in and own it still stands, and as the standard library above shows, that call does sometimes get answered.
We also must note that if someone really does need a fully developed DSL that is Modelica-like and compiles to ModelingToolkit, but is a more fully featured version (for example, has syntax highlighting, gives syntactic compiler errors, supports units, is well-maintained, etc.) then we suggest checking out Dyad which is free for non-commercial use and provides exactly this DSL. Our intention here is not to push out @mtkmodel to Dyad, but instead to note how the ModelingToolkit project has evolved, where the open source aspect has really evolved to thrive around the symbolic compiler but not all of the extra language features. As such, we want to make @mtkmodel like every other DSL as just a potential add-on package, and allow users to pick from the bevy of cool DSLs built on ModelingToolkit, keeping all of the difficulties of developing a language separate from the largely mathematical work of ModelingToolkit.
I just want to end this by saying, I have dedicated almost every day, night, and weekend towards making the Julia open source community thrive. Sometimes hard decisions have to be made, and I think it is clear to everyone that this is one of them. It took us almost 3 years to find this solution and I believe that this version both maximizes the amount of open source-ness in the project, gives people ways to opt out of any GPL-ness, while also giving a sustainable model for the project's future. I hope the complete honesty and transparency of these changes helps everyone understand the reasoning behind the changes. And I, Chris Rackauckas, am available to talk about not just the technical aspects but also the community and funding aspects of ModelingToolkit, SciML, and the rest of the Julia ecosystem at any time. If you have any questions, feel free to reach out.