Urgent.News

What's breaking now, across thousands of outlets.

Tech

TypeScript Without Node.js in Production: What You Gain, What You Give Up

A small TypeScript service often arrives in production with much more than its application code. It may need Node.js, a package-manager layout, production dependencies, startup scripts, environment conventions, and a container assembled to hold everything together. That model is mature and flexible. It is also broader than every workload needs. I have been exploring a narrower question: What if a…

Developers writing TypeScript applications often face a complex deployment process that includes Node.js, package managers, production dependencies, and more. This approach can be broad, incorporating components that may not be necessary for every workload. In response to this, Tysel—an open-source runtime for TypeScript services—has been developed.

It aims to simplify deployment by producing a single executable that includes the TypeScript source code, a validated manifest, compatible dependencies, and the native Tysel runtime.

The process begins during development, where developers write TypeScript and can utilize compatible npm packages. At build time, Tysel compiles the application, integrates it with a native runtime, and outputs a single executable file. This executable contains the application's TypeScript source code, a validated manifest, compatible dependencies, and the Tysel runtime. Importantly, the target machine does not require a separate Node.js runtime, V8, npm, or node_modules to run the application.

One notable feature of Tysel is that it does not convert TypeScript into native machine instructions. Instead, the application JavaScript runs inside an embedded QuickJS-ng isolate, an open-source JavaScript engine. The core functionality of HTTP, storage, secrets management, resource limits, and durable scheduling is handled by a Rust host. This design ensures that Tysel applications are deployed as native binaries rather than relying on a new JavaScript execution model.

To get started with Tysel, users can install the latest stable release on Linux or macOS using a simple script. Once installed, developers can create and run a basic HTTP service using the `tysel init`, `tysel task verify`, and `tysel dev` commands. The generated application employs the Web-standard Fetch model, allowing it to receive and process HTTP requests.

The application can then be packaged for production using the `tysel task release` command, which generates a release build containing the application bundle, a validated manifest, compatibility metadata, source map, and runtime files. This release build also includes additional files for auditing and release compliance.

Under the hood, Tysel's implementation is designed with a minimal number of layers to maximize efficiency. The application language used is TypeScript, compiled down to JavaScript using QuickJS-ng 0.16.2, while the native host is written in Rust. The application API is based on a selected subset of the Web API surface, ensuring compatibility with standard JavaScript constructs. The current implementation supports Linux and macOS, with both x64 and arm64 architectures.

One of the key design principles of Tysel is that application capabilities are explicitly declared and restricted by a contract that includes deployment policy, execution profile, and runtime support. This means that developers can specify exactly which resources their application needs, such as API endpoints or secret keys, without granting it unrestricted authority.

The service's default profile is designed for trusted first-party code, while an isolated profile can be used to run code in a separate worker process with additional security measures, such as Landlock filesystem rules and seccomp syscall filtering.

Tysel also supports durable work, allowing agents and background workflows to interact with external services, wait for approvals, and resume their tasks after a restart. This feature ensures that completed boundaries return their persisted results, maintaining the continuity of execution. The isolated profile further enhances security by running JavaScript in a separate worker process, with additional isolation mechanisms in place on Linux systems.

In terms of performance, Tysel provides benchmark evidence for its releases rather than a single universal performance claim. For a small reference HTTP service, the benchmark results on Linux x64 and Linux arm64 show cold-start times of 6.29 ms and 4.36 ms, respectively, with idle memory consumption of 7.31 MiB and 6.72 MiB. These measurements were taken on GitHub-hosted Ubuntu 24.04 runners and serve as a reference for the minimal performance impact of deploying a TypeScript application as a single executable.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

More from Friday 4 September →