Web Integrations
Twilic ships npm packages that encode and decode binary payloads for common JavaScript web stacks. HTTP integrations use the same MIME type; WebSocket helpers share the same @twilic/core codec.
Content type
Every package exports TWILIC_CONTENT_TYPE:
application/vnd.twilicSend and expect this Content-Type header on Twilic payloads. Integrations reject or skip decoding when the header does not match (configurable with requireContentType: false on parsers).
Use stateless Dynamic or Batch profiles for HTTP request/response. Stateful session compression requires a persistent ordered channel and is not appropriate for typical HTTP APIs. See FAQ — Can I use Twilic over HTTP?.
Packages
| Package | Use with |
|---|---|
@twilic/express | Express middleware |
@twilic/fastify | Fastify plugin |
@twilic/hono | Hono middleware |
@twilic/axios | Axios interceptors |
@twilic/fetch | fetch helpers |
@twilic/websocket | WebSocket frames |
All packages depend on @twilic/core. Install the integration package plus its framework peer dependency (@twilic/websocket needs only @twilic/core).
Express
bun add @twilic/express express @twilic/coreimport express from "express";
import { twilicParser, twilicSend } from "@twilic/express";
const app = express();
app.post("/users", twilicParser(), (req, res) => {
twilicSend(res, { ok: true, received: req.twilicBody });
});Do not mount express.json() before Twilic routes on the same path, or the request body stream will already be consumed. Use a dedicated router or place twilicParser() only on routes that do not use JSON body parsing.
Fastify
bun add @twilic/fastify fastify @twilic/coreimport Fastify from "fastify";
import { twilicParser, twilicPlugin, twilicReply } from "@twilic/fastify";
const app = Fastify();
await app.register(twilicPlugin);
app.post("/users", { preHandler: twilicParser() }, (request, reply) => {
return twilicReply(reply, { ok: true, received: request.twilicBody });
});
// or use the reply decorator:
app.get("/ping", (_request, reply) => reply.twilic({ pong: true }));Hono
bun add @twilic/hono hono @twilic/coreimport { Hono } from "hono";
import { twilicParser, twilicResponse } from "@twilic/hono";
const app = new Hono();
app.post("/users", twilicParser(), async (c) => {
const input = c.var.twilicBody;
return twilicResponse(c, { ok: true, received: input });
});Axios
bun add @twilic/axios axios @twilic/coreimport axios from "axios";
import { createTwilicAxios } from "@twilic/axios";
const client = createTwilicAxios(axios.create());
const { data } = await client.post("/api/users", null, {
twilicBody: { id: 1n, name: "alice" },
});Set twilicResponse: false on a request when you expect a non-Twilic response body.
Fetch
bun add @twilic/fetch @twilic/coreimport { init } from "@twilic/core";
import { twilicFetchJson } from "@twilic/fetch";
// In the browser, initialize the WASM backend once before calling helpers.
await init({ prefer: "wasm" });
const data = await twilicFetchJson("/api/users", {
method: "POST",
twilicBody: { id: 1n, name: "alice" },
});On Node.js, @twilic/core selects the N-API backend by default and init() is still recommended before first use.
Custom codec
Each integration accepts an optional codec object with encode and decode functions. Use createTwilicExpress, createTwilicFastify, createTwilicHono, createTwilicAxios, createTwilicFetch, or createTwilicWebSocket(socket, { codec }) when you need a custom @twilic/core configuration.
WebSocket
bun add @twilic/websocket @twilic/coreimport { init } from "@twilic/core";
import { createTwilicWebSocket } from "@twilic/websocket";
await init();
const twilic = createTwilicWebSocket(new WebSocket("ws://localhost:8788"));
twilic.onMessage((value) => {
console.log(value);
});
twilic.send({ id: 1n, name: "alice" });One WebSocket message equals one Twilic frame. Prefer binary frames. For stateful patches, bind the socket with createTwilicWebSocket(socket, { stateful: true }). See @twilic/websocket and Examples — WebSocket Session.
Related
- JavaScript / TypeScript SDK
- Twilic CLI — encode and decode from the terminal
- Cookbook — API Response with Repeated Structure
- Examples — HTTP Round-Trip — Express / Hono / Fastify + fetch / Axios
- Examples — WebSocket Session —
@twilic/websocketlive stream @twilic/websocketreference