Daslang skips the marshalling layer between script and C++
daslang - high-performance statically strong typed scripting language
At a glance
- What is it?
- Daslang, formerly daScript, is a BSD-3-Clause statically typed scripting language built by Gaijin Entertainment after Lua and Squirrel proved too expensive to call from their ECS engine. It has three execution tiers, a tree-based interpreter, AOT compilation to C++ and an LLVM JIT, plus a package manager, a tree-sitter grammar and an MCP server for AI coding assistants.
- Who is it for?
- Daslang fits a C++ game engine team whose scripting layer is losing frame budget to marshalling, since matching the C++ data layout removes boxing and conversion, and it fits a team that needs scripting to compile ahead of time for console certification. It does not fit a project that wants the language ecosystem of Lua, JavaScript or Python, and it does not fit a team without a C++ toolchain, since even the interpreter is delivered as part of a CMake built native library.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem was marshalling, not speed
Daslang was created at Gaijin Entertainment to solve a specific problem, and the README states it in one line: interop overhead between scripting languages and C++ was eating the frame budget in their ECS game engine. Lua, through LuaJIT, and Squirrel both hit the same wall, because marshaling data back and forth was too expensive.
That framing matters, because it explains the whole design. A scripting language that is fast at running its own code but expensive at talking to the host has not solved the problem for a game engine, where the game logic and the engine objects are the same data. The answer Daslang gives is that the data layout matches C++, with no marshaling, no boxing and no conversion, so script to C++ calls are near-zero cost.
The five core principles in the README are worth reading in full, because they are the specification of what the language is for.
Iteration speed is king, with a full production game recompiling in roughly 5 seconds and hot reload built in. Explicit, not implicit, with no hidden type conversions and no silent allocations, and an options log command that shows exactly what the compiler produces. 99% safe, not 100%, eliminating real-world C++ bugs pragmatically without Rust-level restrictions. If it gets slow, you can fix it, through manual delete to reduce GC pressure or AOT to C++ for native speed. And the language reflects the problem, with a compile-time macro system that lets libraries reshape syntax to match the domain.
That last one is unusual and specific. A macro system that can change the syntax means a library can make its own API read like the problem domain, which is a level of API shaping that most scripting languages do not offer.
Three execution tiers and the hybrid mode between them
The README describes three execution tiers, and the phrasing that all three were planned from day one is doing some work, since it means the tiers are not a later addition.
The order is a fast tree-based interpreter, then AOT compilation to C++, which is described as required for consoles, then JIT via LLVM.
The AOT tier is the one with the most direct constraint attached. Console platforms require ahead-of-time compilation, so a language that wants to run on them has to be able to emit native code, and that is what the C++ output tier is for. The AOT path generates a C++ stub that you compile and link with your host application, so the language does not have to invent its own object format, it emits source in a language your existing toolchain already handles.
./bin/daslang -aot main.das aot_main.cpp
clang++ host.cpp aot_main.cpp -Iinclude lib/liblibDaScript.a lib/liblibUriParser.a -o appThe JIT tier uses LLVM, and it has a specific operational requirement. To use JIT you need the LLVM 16.0.6 shared library at the path lib/LLVM.dll, and the name is fixed because of the dynamic bindings in modules/dasLLVM/bindings/llvm_func.das. Once the library is in place, the invocation is the same shape as any other script run.
./bin/daslang -jit main.dasThe hybrid mode is the most interesting design idea in the list. It uses semantic hashing, so unchanged functions stay AOT and changed ones fall back to the interpreter. The stated purpose is to ship a hotfix without a full rebuild, which for a live game service turns a rebuild into an immediate change.
The reference for the reasoning behind all of this is the design philosophy document at doc/source/reference/design_philosophy.rst.
A package manager, an MCP server and a tree-sitter grammar
The tooling around the language is more developed than a typical research language's, and three pieces stand out.
The first is daspkg, a built-in package manager in utils/daspkg/ that handles installing, updating and building daslang packages, both pure-daslang and C++ native modules.
./bin/daslang utils/daspkg/main.das -- install das-claude
./bin/daslang utils/daspkg/main.das -- install github.com/user/repo
./bin/daslang utils/daspkg/main.das -- search jsonIt installs from the index and from a git URL, and it searches the index. A language with a package manager at this stage is treating itself as a product rather than a research project.
The second is the MCP server in utils/mcp/, which exposes 29 compiler-backed tools to AI coding assistants such as Claude Code. The list is what makes it interesting, because the tools are backed by the compiler rather than by text processing: compilation diagnostics, type inspection, go-to-definition, find-references, AST dump, AOT generation, expression evaluation, parse-aware grep and package management. The transport is stdio and there are no extra build dependencies, and the setup details are in utils/mcp/README.md.
The third is the tree-sitter grammar for the gen2 syntax, in tree-sitter-daslang/. The claim about correctness is strong, that every gen2 file the compiler accepts parses without error, and CMake builds the grammar as a shared library with the target tree_sitter_daslang. The grammar ships highlights.scm for syntax highlighting in tree-sitter capable editors such as Neovim, Helix and Zed, tags.scm for code navigation, and it works with ast-grep for parse-aware search, with a caveat that a daslang pattern is literal code, so metavariables such as $A do not match. There is also a Zed extension in utils/zed-daslang/ and sgconfig files for Linux, macOS and Windows.
The VS Code side is covered by two extensions, one for syntax highlighting and one for language server, linting, debugging and snippets.
Building it, and what the repository contains
Installation is a clone plus a submodule update, which tells you the project vendors some of its dependencies.
git clone https://github.com/GaijinEntertainment/daScript.git daslang
cd daslang
git submodule update --init --recursiveThe build is CMake, and the target is the language binary itself.
cmake -Bbuild -DCMAKE_BUILD_TYPE=Release
cmake --build build --target daslang --config ReleaseEmbedding is handled through a CMake package, so an application calls find_package(DAS) and gets the targets libDaScript and libDaScriptDyn, the second presumably being the dynamic variant given the name. The README points at an external project demo for using daslang as an external dependency including dynamic modules.
The repository layout is large and tells you the scope of the effort. There is src/ for the compiler and runtime, include/ for the public headers, daslib/ for the standard library, modules/ for the optional modules including the dasLLVM one, examples/ with a long list of separate directories covering audio, graphics, gltf, games, benchmarks, a C API library, the package manager, debugging, the MCP integration and more, plus tutorials/, tests/, tests-cpp/, dastest/ and dastest_wasm/ for the test harnesses, benchmarks/ for the performance work, doc/ for the documentation, ci/ for the pipelines, and web/ for the site.
Two entries in that listing are unusual for a language repository. The .claude/ and .codex/ directories at the top level are configuration for AI coding assistants, and there is an AGENTS.md, a CLAUDE.md and a context7.json alongside them. The presence of AI tooling configuration at the root of a language implementation is a sign of where the maintainers think their users are.
There is also a REVIEW.das and REVIEW.md and a REVIEW_COMMON.md, which is an in-language review artefact rather than a review document, and a 3rdparty/ directory with a THIRD_PARTY_NOTICES.md, since the vendored components keep their own licences.
Where Daslang is the wrong choice
The first wrong case is a team that wants an existing scripting ecosystem. Daslang is young, its package index is small, and its standard library, daslib/, is built for game and real-time work rather than for the breadth of Lua or the tooling of JavaScript. A team that needs a specific library, a familiar debugger or an existing corpus of scripts is starting from zero.
The second wrong case is a project that does not already have a C++ core. The whole premise is that the script data layout matches C++ and that calls are near-zero cost because there is no marshalling. If your application is not a C++ program, there is no host to interop with, the argument for the language disappears, and what remains is a statically typed language with a small ecosystem and a new toolchain to learn.
The third wrong case is a team that wants memory safety guarantees rather than pragmatic ones. The README is explicit that the goal is 99% safe, not 100%, eliminating real-world C++ bugs pragmatically without Rust-level restrictions. If your requirement is a guarantee, or a proof, this is the wrong side of that trade.
The fourth wrong case is a team unwilling to own a compiler. The interpreter is not a script you can drop in, it is a native library built from a CMake project, and the AOT path emits C++ you then compile with your own toolchain. That is a reasonable arrangement for a studio that already has a C++ build system, and a burden for anyone who does not.
The fifth wrong case is assuming the JIT is free. The JIT needs a specific LLVM 16.0.6 shared library at a fixed path, so the deployment story is more involved than the interpreter alone, and on a platform where you cannot ship that library you are limited to the interpreter and the AOT tier.
How it differs from Lua embedded in C++
The comparison worth making is with Lua and LuaJIT, since that is the tool the design was made to replace, and the difference is not speed so much as representation.
In Lua, calls between the script and the host cross a marshaling boundary, and that cost is the wall the design hit. When the host owns the data, for example an entity struct with a transform and a velocity, every read from the script crosses that boundary. LuaJIT made the interpreter extremely fast, and the README credits that implicitly by naming it as a wall the design hit, not a failure.
Daslang's answer is to make the script's data layout the C++ layout. A struct in the script is the struct in the host, a field is a field, and a call passes a reference rather than a boxed value. The cost of the marshalling disappears because there is nothing to marshal. The price is that the language is not dynamically typed, and it cannot be, since the whole point is a static correspondence with the host's types.
The second difference is the execution strategy. LuaJIT is the runtime the design was made to replace. Daslang has three, and the hybrid mode is the distinguishing one, where semantic hashing lets the runtime decide per function whether to keep the compiled path or fall back to the interpreter after a source change. For a live service that needs to ship a hotfix, that is a capability rather than a convenience.
The third difference is what the language lets you do to your own code. The compile-time macro system can reshape syntax, so a game-specific library can read like the domain rather than like a set of function calls.
The fourth difference is the standard library. daslib/ and the modules/ directory, including the dasLLVM module for the JIT, are built for game and real-time work. Lua's ecosystem is general purpose. Daslang's is narrow, which is correct for its purpose and a limitation for anything else.
Editorial conclusion
Daslang fits a C++ game engine team whose scripting layer is losing frame budget to marshalling, since matching the C++ data layout removes boxing and conversion, and it fits a team that needs scripting to compile ahead of time for console certification. It does not fit a project that wants the language ecosystem of Lua, JavaScript or Python, and it does not fit a team without a C++ toolchain, since even the interpreter is delivered as part of a CMake built native library. Before adopting it, build the interpreter and try the AOT path on your own code, since the design philosophy is in doc/source/reference/design_philosophy.rst, and note that the current tag is v0.6.5-RC2 from 2026-10-15 with the last push on the same day.
Frequently asked questions
How do I build the Daslang compiler and interpreter?
Clone the repository, run git submodule update --init --recursive, then configure with cmake -Bbuild -DCMAKE_BUILD_TYPE=Release and build with cmake --build build --target daslang --config Release. The project is BSD 3-Clause licensed and requires a C++ toolchain and CMake.
How does Daslang compile a script to native code?
The AOT path generates a C++ stub with ./bin/daslang -aot main.das aot_main.cpp, and you compile and link it with your host application, for example clang++ host.cpp aot_main.cpp -Iinclude lib/liblibDaScript.a lib/liblibUriParser.a -o app. AOT is described as required for consoles.
What does the Daslang JIT require?
You need the LLVM 16.0.6 shared library at the path lib/LLVM.dll, and the name is fixed because of the dynamic bindings in modules/dasLLVM/bindings/llvm_func.das. Once it is in place, you run ./bin/daslang -jit main.das. The hybrid mode uses semantic hashing so unchanged functions stay AOT and changed ones fall back to the interpreter.
Does Daslang have a package manager and editor support?
Yes. daspkg in utils/daspkg/ installs, updates and builds packages, including pure-daslang and C++ native modules, from an index or a git URL. There is a tree-sitter grammar in tree-sitter-daslang/ for highlighting, code navigation and ast-grep search, two VS Code extensions, a Zed extension, and an MCP server in utils/mcp/ exposing 29 compiler-backed tools to AI coding assistants.
Who develops Daslang and what is the current release?
It was created at Gaijin Entertainment and the repository is maintained under that organisation. The current tag is v0.6.5-RC2 from 2026-10-15, with v0.6.5-RC1 on 2026-10-08 and a dasllama v0.6.6-RC1 tag on 2026-10-09, and the last push to master was on 2026-10-15.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/gaijinentertainment-dascript)Was this useful?