The sandbox project to investigate a footprint of various embedded languages.
The criteria for the language to be included into the project:
-
C/C++ only (to ensure the best portability);
-
No extra compilation dependencies (to build with the bare devkits);
-
Actively maintained (to compile without its source code changes);
-
Strong typing (to reduce the number of possible errors);
-
Permissive license for both open source and commercial projects;
The syntax of the language should be friendly to the required source code transformations. The original list of the languages satisfied those requirements, but it has been extended later to include other languages for the reference or testing purposes.
|
Note
|
While it’s possible to transform the bytecode (where available) instead of the original source code (thus lifting the requirement for its syntax), it could be not an easy feat, esp. if the bytecode format is proprietary or could change any time. |
Examples of possible source code transformations:
-
Stripping debug and unused functionality;
-
Minification of private symbols;
-
Removing all newlines.
You will need:
-
make
-
a C and a C++ compiler (supporting at least C++20)
-
svn
-
git
-
zip
-
cython3
Sorted by the footprint (disk) size. The example code is the declaration of the function that concatenates the fixed string ("Hello, ") with the output of the external function ("read" that should return "world").
All code is verified to be properly returing "Hello, world" as the result of invoking that function. Resident set size (RSS) is measured during execution of "read" function.
- Platform
-
Linux 6.1.0-39-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.148-1 (2025-08-26) x86_64 GNU/Linux
| Language | ELF Size (KiB) | RSS (KiB) | Example Code |
|---|---|---|---|
TinyScheme |
84 |
3176 |
|
Chibi-Scheme |
263 |
3684 |
|
Lua |
271 |
1916 |
|
Squirrel |
278 |
1908 |
|
Gravity |
508 |
3604 |
|
Janet |
811 |
4924 |
|
QuickJS |
983 |
1968 |
|
ArkScript |
1057 |
4660 |
|
ChaiScript |
1246 |
4572 |
|
AngelScript |
2064 |
4908 |
|
Python |
3609 |
8956 |
|
Each language contains the section how to declare external function used by the script (C++ lambda returning string "world").
TinyScheme is a lightweight Scheme interpreter that implements as large a subset of R5RS as was possible without getting very large and complicated. The TinyScheme project has slowly acquired foothold in many open-source projects over the years, notably GIMP.
link:src/tinyscheme.cc[role=include]Notes:
-
The project includes a REPL interpreter.
Lua is a powerful, efficient, lightweight, embeddable scripting language. It supports procedural programming, object-oriented programming, functional programming, data-driven programming, and data description.
- Homepage
- Documentation
- Source code
link:src/lua.cc[role=include]Notes:
-
The project includes a REPL interpreter.
-
New-lines sensitive (however they could be replaced by spaced).
Chibi-Scheme is a very small library intended for use as an extension and scripting language in C programs. In addition to support for lightweight VM-based threads, each VM itself runs in an isolated heap allowing multiple VMs to run simultaneously in different OS threads. Despite the small size, Chibi-Scheme attempts to do The Right Thing. The default settings include:
-
a full numeric tower, with rational and complex numbers
-
full and seemless Unicode support
-
low-level and high-level hygienic macros
-
an extensible module system
Specifically, the default REPL language contains all bindings from R7RS small, available explicitly as the (scheme small) library. Chibi-Scheme is known to work on 32 and 64-bit Linux, FreeBSD, NetBSD, OpenBSD and OS X, Plan 9, Windows, iOS, Android, ARM and Emscripten. Basic support for native Windows desktop also exists.
- Homepage
- Documentation
- Source code
link:src/chibi-scheme.cc[role=include]Notes:
-
Chibi-Scheme has the extensive library (besides support of standard Scheme libraries), few examples are:
-
(chibi crypto rsa) - RSA public key encryption
-
(chibi crypto sha2) - SHA-2 hash
-
(chibi json) - JSON reading and writing
-
Squirrel is a high level imperative, object-oriented programming language, designed to be a light-weight scripting language offering a wide range of features like:
-
dynamic typing
-
delegation
-
classes & inheritance
-
higher order functions
-
lexical scoping
-
generators
-
cooperative threads (coroutines)
-
tail recursion
-
exception handling
-
automatic memory management
-
optional 16bits characters strings
Squirrel is inspired by languages like Python, ECMAScript and especially Lua (the API is very similar and the table code is based on the Lua one).
- Homepage
- Documentation
- Source code
link:src/squirrel.cc[role=include]Notes:
-
The project includes a REPL interpreter.
Arkscript is:
-
a functional language: every parameter is passed by value, everything is immutable unless you use mut to define a mutable variable
-
powerful: it can handle object oriented programming in a very elegant way with its closures and explicit captures
-
a Lisp-like, but with less parentheses:
[…]is expanded to(list …)and{}to(begin …).
It also has a REPL with autocompletion and coloration
- Homepage
- Documentation
- Source code
link:src/arkscript.cc[role=include]Gravity is a powerful, dynamically typed, lightweight, embeddable programming language written in C without any external dependencies (except for stdlib). It is a class-based concurrent scripting language with modern Swift-like syntax.
Gravity supports procedural programming, object-oriented programming, functional programming and data-driven programming. Thanks to special built-in methods, it can also be used as a prototype-based programming language.
Gravity has been developed from scratch for the Creo project in order to offer an easy way to write portable code for the iOS and Android platforms.
- Homepage
- Documentation
- Source code
link:src/gravity.cc[role=include]Notes:
-
The project doesn’t includes a REPL interpreter, but has a compiler allowing to compile and run its scripts.
Janet is a functional and imperative programming language and bytecode interpreter. It is a lisp-like language, but lists are replaced by other data structures (arrays, tables (hash table), struct (immutable hash table), tuples). The language also supports bridging to native code written in C, meta-programming with macros, and bytecode assembly.
There is a REPL for trying out the language, as well as the ability to run script files. It runs on Windows, Linux, macOS, BSDs, and should run on other systems with some porting.
- Homepage
- Documentation
- Source code
link:src/janet.cc[role=include]ChaiScript is one of the only embedded scripting language designed from the ground up to directly target C++ and take advantage of modern C++ development techniques, working with the developer how they would expect it to work. Being a native C++ application, it has some advantages over existing embedded scripting languages:
-
It uses a header-only approach, which makes it easy to integrate with existing projects.
-
It maintains type safety between the C++ application and the user scripts.
-
It supports a variety of C++ techniques including callbacks, overloaded functions, class methods, and STL containers.
The syntax resembles ECMAScript.
- Homepage
- Documentation
- Source code
link:src/chaiscript.cc[role=include]Notes:
-
The project includes a REPL interpreter.
-
The compilation time is quite noticeable.
The scripting language follows the widely known syntax of C/C++, but without the need to worry about pointers and memory leaks. Contrary to most scripting languages, AngelScript uses the common C/C++ datatypes for more efficient communication with the host application.
link:src/angelscript.cc[role=include]Notes:
-
The project doesn’t includes a REPL interpreter.
Python is an interpreted, high-level and general-purpose programming language.
- Homepage
- Documentation
- Source code
link:src/python/main.cc[role=include]Notes:
-
Indentation and new lines sensitive.
-
The test application couldn’t work without a subset of the Python standard library. It’s embedded as a zip file into the executable, however it’s not a portable solution.
Cython is an optimising static compiler for both the Python programming language and the extended Cython programming language (based on Pyrex). It makes writing C extensions for Python as easy as Python itself.
It requires few more steps to use comparing with vanilla C/C++ usage, however the productivy gain outweights the build process changes. Please note that we don’t use --embed feature (that generates main) as we need
to extract Python libraries first. Currently Cython doesn’t support customization of main(), and it assumes that Python modules already available (not in our case). However, in general, Cython’s main is not used much, as host environment usually have additional
functionality besides calling Python code.
The examples of the steps involved in using Cython are described below.
.pyx-files:link:src/python/cython_main.pyx[role=include].c/.h-files:link:Makefile[role=include]Please note that the name of the .pyx-file is used for exporting PyInit-function (PyInit_cython_main below).
link:src/python/main.cc[role=include]QuickJS is a small and embeddable Javascript engine. It supports the ES2020 specification including modules, asynchronous generators, proxies and BigInt.
- Homepage
- Documentation
- Source code
link:src/qjs.cc[role=include]