JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1372
  • Score
    100M100P100Q124029F
  • License MIT

High-performance WASM-powered HTTP server framework

Package Exports

  • @sylphx/gust

Readme

@sylphx/gust

High performance functional HTTP server powered by WASM.

Features

  • Fast - WASM-powered HTTP parser and Radix Trie router
  • Functional - Composable middleware with pipe() and compose()
  • Type-safe - Full TypeScript support with path param inference
  • Zero dependencies - Core functionality built-in
  • Bun-first - Optimized for Bun runtime

Built-in Middleware

Category Features
Protocol HTTP/1.1, HTTP/2, WebSocket, SSE
Security CORS, CSRF, Security headers, Rate limiting
Auth Basic, Bearer, API Key, HMAC, JWT, Session
Performance Compression, Caching, Circuit breaker, Cluster
Observability Tracing, Logging, Health checks, OpenTelemetry
Utilities Validation, Body parsing, Cookies, Static files

Installation

bun add @sylphx/gust

Quick Start

import { serve, router, get, json } from '@sylphx/gust'

const home = get('/', () => json({ message: 'Hello World' }))
const user = get('/users/:id', (ctx) => json({ id: ctx.params.id }))

const app = router({ home, user })

// Type-safe URL generation
app.url.home()           // "/"
app.url.user({ id: 42 }) // "/users/42"

serve({ port: 3000, fetch: app.handler })

Examples

With Middleware

import {
  serve,
  router,
  get,
  post,
  json,
  compose,
  cors,
  compress,
  rateLimit,
  jwtAuth,
  getJwtPayload,
  parseJsonBody,
} from '@sylphx/gust'

// Public routes
const health = get('/health', () => json({ status: 'ok' }))

// Protected routes
const me = get('/me', (ctx) => json(getJwtPayload(ctx)))
const createPost = post('/posts', async (ctx) => {
  const body = await parseJsonBody(ctx)
  return json({ created: body })
})

const protectedRoutes = compose(
  jwtAuth({ secret: process.env.JWT_SECRET! }),
  router({ me, createPost }).handler
)

const publicRoutes = router({ health }).handler

const app = compose(
  cors(),
  compress(),
  rateLimit({ max: 100, window: 60000 }),
  (ctx) => ctx.path.startsWith('/me') || ctx.path.startsWith('/posts')
    ? protectedRoutes(ctx)
    : publicRoutes(ctx)
)

serve({ port: 3000, fetch: app })

WebSocket

import { serve, websocket } from '@sylphx/gust'

serve({
  port: 3000,
  fetch: websocket({
    open: (ws) => console.log('Connected'),
    message: (ws, msg) => ws.send(`Echo: ${msg}`),
    close: (ws) => console.log('Disconnected'),
  }),
})

Static Files

import { serve, serveStatic, router, get, json } from '@sylphx/gust'

const api = get('/api/hello', () => json({ hello: 'world' }))
const app = router({ api })

serve({
  port: 3000,
  fetch: (ctx) => {
    if (ctx.path.startsWith('/api')) {
      return app.handler(ctx)
    }
    return serveStatic({ root: './public' })(ctx)
  },
})

Health Checks (Kubernetes)

import { serve, router, get, liveness, readiness, health, memoryCheck } from '@sylphx/gust'

const live = get('/healthz', liveness())
const ready = get('/ready', readiness([memoryCheck(90)]))
const detailed = get('/health', health({ checks: [memoryCheck(90)], detailed: true }))

const app = router({ live, ready, detailed })

serve({ port: 3000, fetch: app.handler })

Validation

import { serve, router, post, json, compose, validate, object, string, email, number, getValidated } from '@sylphx/gust'

const createUser = post('/users', compose(
  validate({
    body: object({
      name: string({ minLength: 1 }),
      email: email(),
      age: number({ min: 0 }),
    }),
  }),
  async (ctx) => {
    const data = getValidated(ctx)
    return json({ user: data })
  }
))

const app = router({ createUser })

serve({ port: 3000, fetch: app.handler })

Session & CSRF

import { serve, router, get, post, html, json, compose, session, csrf, getCsrfToken, getSession } from '@sylphx/gust'

const form = get('/form', (ctx) => html(`
  <form method="POST" action="/submit">
    <input type="hidden" name="_csrf" value="${getCsrfToken(ctx)}">
    <button type="submit">Submit</button>
  </form>
`))

const submit = post('/submit', (ctx) => {
  const sess = getSession(ctx)
  sess.data.visits = ((sess.data.visits as number) || 0) + 1
  return json({ visits: sess.data.visits })
})

const app = compose(
  session({ secret: 'your-secret' }),
  csrf({ secret: 'csrf-secret' }),
  router({ form, submit }).handler
)

serve({ port: 3000, fetch: app })

Circuit Breaker

import { serve, router, get, json, compose, circuitBreaker } from '@sylphx/gust'

const external = get('/external', compose(
  circuitBreaker({
    failureThreshold: 5,
    resetTimeout: 30000,
  }),
  async () => {
    const res = await fetch('https://api.example.com/data')
    return json(await res.json())
  }
))

const app = router({ external })

serve({ port: 3000, fetch: app.handler })

OpenTelemetry

import { serve, router, get, json, compose, otel, createTracer, consoleExporter } from '@sylphx/gust'

const tracer = createTracer(consoleExporter)

const hello = get('/', () => json({ hello: 'world' }))
const app = router({ hello })

serve({
  port: 3000,
  fetch: compose(otel({ tracer }), app.handler),
})

Cluster Mode

import { clusterServe, router, get, json } from '@sylphx/gust'

const index = get('/', () => json({ pid: process.pid }))
const app = router({ index })

clusterServe({
  port: 3000,
  fetch: app.handler,
  workers: 4,
})

API Reference

Response Helpers

import { json, text, html, redirect, notFound, badRequest, unauthorized, forbidden, serverError } from '@sylphx/gust'

json({ data: 'value' })           // application/json
text('Hello')                      // text/plain
html('<h1>Hello</h1>')            // text/html
redirect('/new-path')              // 302 redirect
redirect('/new-path', 301)         // 301 redirect
notFound()                         // 404
badRequest()                       // 400
unauthorized()                     // 401
forbidden()                        // 403
serverError()                      // 500

Composition

import { compose, pipe } from '@sylphx/gust'

// compose: right-to-left (outer to inner)
const app = compose(cors(), compress(), handler)

// pipe: left-to-right (first to last)
const app = pipe(handler, compress(), cors())

Type-Safe Routes

import { router, get, post, prefix, merge } from '@sylphx/gust'

// Routes with typed params
const user = get('/users/:id', (ctx) => {
  ctx.params.id  // string (type-safe!)
  return json({ id: ctx.params.id })
})

const post = get('/users/:userId/posts/:postId', (ctx) => {
  ctx.params.userId  // string
  ctx.params.postId  // string
  return json(ctx.params)
})

// Named routes with URL generation
const app = router({ user, post })
app.url.user({ id: 42 })                    // "/users/42"
app.url.post({ userId: 1, postId: 99 })     // "/users/1/posts/99"

// Route composition
const apiRoutes = prefix('/api', { user, post })
const allRoutes = merge(apiRoutes, otherRoutes)

License

MIT


✨ Powered by Sylphx