@netscript/workers
workers
Background work with a queue, retries and a tracer.
Open source
NetScript is the framework Devocracy uses on client work. It is open source, so anyone can read how your system is put together — including whoever maintains it after us.
Why it exists
One side renames a field, the other side keeps asking for the old one, and nothing complains until a customer does. NetScript writes that agreement down once and generates both sides from it, so a change like that stops the build instead of the order.
The chain
Five steps, five real files, copied from the published documentation.
Method, input and output are bound before any handler exists, so both sides compile against the same definition.
import { createCrudContract } from '@netscript/contracts/crud';
import { UserCreateInput, UserSchema, UserUpdateInput } from '@database/zod';
export const UsersCrudContractV1 = createCrudContract({
resource: 'users',
entitySchema: UserSchema,
createSchema: UserCreateInput,
updateSchema: UserUpdateInput,
});A response that drifts from the contract fails at build time, not in production.
import { v1 } from '@my-app/contracts';
export const UsersV1 = {
list: v1.users.list.handler(async ({ input }) => {
return { items: seededUsers, pagination: { total: seededUsers.length } };
}),
updateStatus: v1.users.updateStatus.handler(async ({ input }) => {
return { updated: true, id: input.id, status: input.status };
}),
};CORS, request logging, an OpenAPI document, Scalar docs, the RPC endpoint, service info and health checks are wired by the preset.
import { defineService } from '@netscript/service';
import { router } from './router.ts';
const service = await defineService(router, {
name: 'users',
port: 3000,
});The client is generated from the same contract, so a rename on the server is a compile error in the front end.
import { createServiceClient } from '@netscript/sdk/client';
import { createQueryFactories } from '@netscript/sdk/query';
import { ordersContract } from '@contracts';
export const ordersClient = createServiceClient<typeof ordersContract>({
contract: ordersContract,
serviceName: 'orders',
});
export const api = createQueryFactories({
orders: { contract: ordersContract, client: ordersClient },
});
const recent = await ordersClient.list({ limit: 10 });An in-memory recorder makes a span assertable in a unit test without an OTLP endpoint.
import { withSpan } from '@netscript/telemetry/tracer';
import { createInMemorySpanRecorder } from '@netscript/telemetry/testing';
const tracer = createInMemorySpanRecorder();
const total = await withSpan(tracer, 'job.import', async (span) => {
span.setAttribute('netscript.job.source', 'erp-sync');
return 42;
});
const [snapshot] = tracer.snapshots();First-party plugins
Each one is a package in the same repository, under the same licence. There is no paid tier.
@netscript/workers
Background work with a queue, retries and a tracer.
@netscript/sagas
Long-running transactions, compensated when a step fails.
@netscript/triggers
Scheduled and event-driven execution, traced like any call.
@netscript/streams
Server-sent events as a first-class transport.
@netscript/auth
Identity and sessions, wired into the service preset.
@netscript/ai
Model calls behind the same contracts as everything else.
Deploy
netscript deploy list --json
netscript deploy kubernetes plan --project-root . --output-dir .deploy/kubernetes
netscript deploy azure-aks up --project-root . --output-dir .deploy/azure-aks
netscript deploy azure-aks down --project-root . --output-dir .deploy/azure-aksRegistered targets
deno-deployNative deno deploy CLI, with a preflight guardwindows-serviceWindows service via Servylinux-servicesystemd unitdockerCompose adapter, six operationscomposeCompose adapter, six operationskubernetesDelegated to the Aspire AppHostcloud-runBuild, push, gcloud run deployazure-acaDelegated to the Aspire AppHostazure-app-serviceDelegated to the Aspire AppHostazure-aksDelegated to the Aspire AppHostA Windows service and a Kubernetes deployment come out of the same project definition.
Agent surface
An agent gets a fixed list of things it may run. Everything else is refused.
Tool results are capped rather than truncated silently.
Install
It is still in beta, so the API can move between releases. Pin the version.
deno install --global --allow-all --name netscript jsr:@netscript/cli@0.0.1-beta.11Next step
Your project does not have to run on NetScript. The way of working comes either way.