Simnaril
Simnaril is a TypeScript library for simulating HTTP services in tests and local development. Each simulated service stores its state in memory and runs in the same Node.js process as your application.
Application code uses its normal URLs and HTTP client. Tests set up the service’s state before calling the application and inspect that state afterward.
Install
Section titled “Install”Simnaril requires Node.js 24 or later:
pnpm add -D @kensio/simnarilThe package provides the building blocks for your simulations. You define the resources and behavior that your application needs from each external service.
Simulate a resource
Section titled “Simulate a resource”Create an API, add a resource, and register the API under the origin your application calls:
import { SimApi, SimEnvironment } from "@kensio/simnaril";
interface Widget { id: string; name: string;}
const api = new SimApi();const widgets = api.resource<Widget>({ path: "/widgets" });widgets.seed({ id: "widget-1", name: "First widget" });
using environment = new SimEnvironment();environment.register("https://api.example.com", api);
const response = await fetch("https://api.example.com/widgets/widget-1");const widget = (await response.json()) as Widget;console.log(widget.name); // "First widget"widgets.seed() stores an entity that the API can return. The fetch() call
reaches that API inside the current Node.js process. HTTP updates to the
resource also change the state available through widgets.get().
The using declaration disposes the environment when the current scope ends.
Requests to origins outside every active simulation fail by default.
The main objects
Section titled “The main objects”| Object | What it does |
|---|---|
SimEnvironment |
Connects outgoing HTTP requests to registered services and manages interception. |
SimApi |
Defines routes, middleware, and error responses for one service. |
SimResource |
Stores entities and provides methods to read and change their state. |
RestResource |
Adds HTTP routes to a SimResource and exposes the same state methods. |
api.resource() creates the state and HTTP routes together. You can also
create a SimResource separately and expose it through more than one API.
Use the simulation in your application
Section titled “Use the simulation in your application”Put service definitions in a factory function. A test calls the factory, seeds the resources it needs, and runs application code. The same factory can start the simulated services in your Node.js development entry point.
- Getting started walks through a complete example and a test.
- REST resources explains the default routes and how to change them.
- Custom operations shows how to add service-specific behavior.
- Composing a simulation puts several services in one reusable factory.
