FunctionalScript: A Purely Functional Subset of JavaScript That Compiles Data, Not Code
FunctionalScript is a safe purely functional subset of JavaScript
At a glance
- What is it?
- FunctionalScript is a strict subset of ECMAScript that bans side effects and compiles modules to JSON or JavaScript. It is aimed at developers who want safe, portable data expressions, but its current compiler only handles a narrow slice of the language.
- Who is it for?
- Adopt FunctionalScript if you need a side-effect-free, JSON-compatible data language that can run as plain JavaScript without a build step, especially for config files, query expressions, or smart-contract prototypes. Do not adopt it if you need functions, computed expressions, or any standard library, since the compiler does not support them yet.
- Can I use it commercially?
- Yes. MIT 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 JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Star history
- functionalscript/functionalscript74 ★ · +6
| Repository | 2026-08-27 | 2026-10-22 |
|---|---|---|
| functionalscript/functionalscript | 68 | 74 |
6 Stars in the last 56 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
What FunctionalScript Solves and Who It Targets
FunctionalScript solves a specific problem: how to write JavaScript that is guaranteed to be free of side effects and safe to run anywhere. The README frames it as removing everything that makes JavaScript unsafe, insecure, or less portable, rather than inventing a new syntax. It targets developers who want a subset of JavaScript that is valid JavaScript, so no build step is needed. The intended use cases are broad: embedding safely in any JS application, using it as a JSON-with-expressions format, as a query language, or as a smart contract language in DeFi. The key audience is not the average JavaScript developer but those who need a declarative, side-effect-free data layer that can interoperate with existing JS tooling.
The Core Mechanism: Compile Evaluates, Not Transpiles
The compiler works in the opposite direction from a typical transpiler. A FunctionalScript module is already valid JavaScript, so running it requires no compilation. Instead, the `fjs compile` command evaluates the module, resolves every `import`, and emits the data that the module exports. The output format depends on the file extension: `.f.js` produces JavaScript that preserves the object graph, while `.json` produces a plain JSON tree. The README gives a concrete example: a module that imports a string constant and exports an array with shared references. The JavaScript output uses a `const` declaration to keep the shared value, so the object graph is preserved. The JSON output expands shared values, and types like `bigint` and `undefined` are not available. This mechanism is a significant design choice: it means the compiler is not translating syntax but evaluating a restricted language to a serializable value.
Getting Started: The fjs CLI and Its Commands
Installation is via npm: `npm install -g functionalscript`, or run it without installing using `npx functionalscript <command>`. The CLI exposes several commands. `fjs test` runs the test suite, which the README calls 'emergent testing'. `fjs compile` is the core command, taking an input module and producing JavaScript or JSON. `fjs cas` provides content-addressable storage with `add`, `get`, and `list` subcommands. `fjs mcp` starts an MCP server over stdio that exposes the CAS and Evo as tools. `fjs ci` generates a GitHub Actions workflow. `fjs web` serves a directory over HTTP. `fjs run` executes a module as a Node program. `fjs help` prints all commands and their short aliases. The compile command is straightforward: `fjs compile input.f.js output.f.js` for JavaScript, or `fjs compile input.f.js output.json` for JSON. The README notes that the compiler currently accepts only `import` statements, `const` declarations, and data expressions such as objects, arrays, strings, numbers, `bigint`, booleans, `null`, and `undefined`.
The Hard Limitation: No Functions, No Computed Expressions
The most significant limitation is that the compiler does not support functions or computed expressions yet. The README states this explicitly: 'Functions and computed expressions are not supported yet.' This means you cannot write anything like `const x = a + b` or `function f() { return 1 }`. The language is effectively a data description language with imports and constants. This is a severe constraint for any real-world use beyond static configuration. The README points to `spec/todo/` for features not yet implemented, but it does not list a timeline. If you need any logic beyond literal values, FunctionalScript is the wrong tool today. The design principle of no side effects is strict, with no `unsafe` escape hatch, but that purity comes at the cost of expressiveness.
Design Principles: Purity Without Exceptions
FunctionalScript enforces a strict no-side-effect rule. The README states that any JavaScript statement, expression, or function that has a side effect is not allowed, and there are no exceptions, unlike Rust's `unsafe` or C#'s unsafe contexts. This is a bold design choice. It also has no standard library; only a safe subset of the standard JavaScript API can be used without referencing other modules. A module can depend only on another FunctionalScript module. These principles ensure that any module is a valid JavaScript module and can run without a build step. However, the absence of a standard library means you cannot rely on common utilities like `Math.random` or `Date.now`, which are inherently side-effectful or non-deterministic. This makes FunctionalScript suitable for deterministic data processing but not for general-purpose programming.
Alternatives: JSON5, asm.js, and TypeScript as Contrasts
FunctionalScript draws inspiration from several existing approaches, which serve as natural alternatives. JSON and JSON5 are subsets of JavaScript values, and JSON is a subset of FunctionalScript values. If you only need static data, JSON5 is a simpler, mature option that allows comments and unquoted keys, but it does not support imports or expressions. asm.js is a subset of JavaScript that compiles to efficient machine code, but it is not purely functional and has side effects. TypeScript is a superset of JavaScript that adds static types but does not enforce purity. The key difference is that FunctionalScript enforces purity at the language level, which neither JSON5 nor TypeScript does. If you need type safety, TypeScript is a more developed choice. If you need a data format, JSON5 is more practical. FunctionalScript sits between them, offering a controlled environment for data expressions.
Maintenance, Licensing, and the Experimental Status
The repository is a monorepo distributed under the MIT license, which is permissive and allows commercial use without restrictions. The README lists sponsors, but there are no recent releases retrieved, and the last push is unknown. This suggests the project may be in an early or low-activity phase. The maintenance cost for a user is low because modules run as plain JavaScript, but the compiler itself is the moving part. The `fjs ci` command generates a GitHub Actions workflow, which indicates a commitment to automated testing, but the 'emergent testing' approach is not detailed. For adoption, you should verify the current state of the `spec/todo/` directory to understand what is missing. The lack of a version history and the narrow compiler scope mean you should treat it as a prototype. The MIT license gives you freedom, but the project's maturity is unproven.
Editorial conclusion
Adopt FunctionalScript if you need a side-effect-free, JSON-compatible data language that can run as plain JavaScript without a build step, especially for config files, query expressions, or smart-contract prototypes. Do not adopt it if you need functions, computed expressions, or any standard library, since the compiler does not support them yet. Before adopting, verify whether the current data-only subset covers your use case, and check the spec/todo/ directory for planned features. The project is MIT-licensed, but with no recent releases and a narrow compiler, treat it as an experimental tool rather than a production dependency.
Frequently asked questions
Is FunctionalScript a separate language or a subset of JavaScript?
A strict subset of ECMAScript and JavaScript. Any FunctionalScript module is a valid JavaScript module, so no additional build step is required to run it. The abbreviation is FJS, carried by the fjs CLI and the fjs/ directory.
How do I get the fjs command without installing anything globally?
Run it through npx as npx functionalscript <command>. The documented alternative is npm install -g functionalscript, which puts fjs on your PATH.
Why does fjs compile refuse to write output.json for a shared value?
JSON is a tree and cannot spell a node reached twice, so the compiler prints output.json - error: no JSON spelling for a shared node instead of writing two copies. The .data.js output keeps the node shared with a single $0 binding.
Does FunctionalScript have a standard library or an unsafe escape hatch?
It has no standard library: only a safe subset of the standard JavaScript API is usable without referencing other modules. Side effects are disallowed with no exceptions, and the project states there is no unsafe code of the kind found in Rust and C#.
Which licence is FunctionalScript released under, and how is it versioned?
MIT, in a monorepo that also carries a Cargo workspace. The npm package is at version 0.53.0, the repository publishes no GitHub releases, and the last push to the main branch was on 2026-09-30.
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/functionalscript-functionalscript)Star history chart for your README
[](https://hysenlabs.com/projects/functionalscript-functionalscript)