npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sourceregistry/sveltekit-service-manager

v1.1.2

Published

A minimal, production-oriented service gateway for SvelteKit.

Readme

🔧 @sourceregistry/sveltekit-service-manager

npm version License CI Codecov

A minimal, production-oriented service gateway for SvelteKit.

This library provides a structured way to expose backend services through versioned gateway routes while keeping services modular, testable, and HMR-safe.


Why this exists

SvelteKit routes are powerful, but for larger backends you often want:

  • a single gateway (/api/v1/services/...)
  • modular services with their own routers and lifecycle
  • internal calls without HTTP
  • safe hot reload during development
  • optional Express / Node middleware reuse
  • a typed client to call services from the browser

This project solves that without introducing a full framework.


Features

  • 🚪 Versioned service gateways (/api/v1/services/<service>/<path…>)
  • 🔐 Per-gateway allowlists
  • 🔁 Clean Vite HMR (cleanup + route reset + re-register)
  • 🧭 Fast, typed service-relative router
  • 🧠 Internal service calls (no HTTP hop)
  • 🛡️ Middleware guards
  • 🔌 Express / Node middleware compatibility (Fetch adapter)
  • 🌐 Typed client-side service caller

Project structure

├── src
│   ├── lib
│   │   ├── client          # Client-side service caller
│   │   └── server
│   │       └── helpers
│   └── routes
│       └── api
│           └── v1
│               └── services
│                   └── [service_name]
│                       └── [...catch]
│                           └── +server.ts
├── static
└── tests
    └── services

Installation

npm i @sourceregistry/sveltekit-service-manager

In this repository you may see $lib/server/index.js. In production always import from the package.


Gateway setup

Example gateway route

src/routes/api/v1/services/[service_name]/[...catch]/+server.ts

import { ServiceManager } from '@sourceregistry/sveltekit-service-manager';

const { endpoint, access } = ServiceManager.Base(undefined, {
  accessKey: 'api:v1'
});

export const { GET, POST, PUT, DELETE, PATCH, HEAD } = endpoint;

// Allow only selected services through this gateway
access('ping', 'users');

This exposes:

/api/v1/services/ping/*
/api/v1/services/users/*

Multiple gateways (public / internal)

Each gateway gets its own allowlist, isolated even across HMR:

// Public API
ServiceManager.Base(undefined, { accessKey: 'public' }).access('ping');

// Internal API
ServiceManager.Base(undefined, { accessKey: 'internal' }).access('admin', 'metrics');

Defining a service

Router-based service (recommended)

import { Router, Action, ServiceManager } from '@sourceregistry/sveltekit-service-manager';

const router = Router()
  .GET('/health', () => Action.success(200, { ok: true }))
  .GET('/echo/[msg]', ({ params }) =>
    Action.success(200, { msg: params.msg })
  );

export const service = {
  name: 'ping',
  route: router
};

export default ServiceManager
  .Load(service, import.meta)
  .finally(() => console.log('[Service]', `[${service.name}]`, 'Loaded'));

Accessible via:

/api/v1/services/ping/health
/api/v1/services/ping/echo/hello

Hot Module Reloading (HMR)

When loading a service with:

ServiceManager.Load(service, import.meta)

The following happens automatically during Vite HMR:

  1. cleanup() is called (if defined)
  2. Router routes are fully reset
  3. Service is unregistered
  4. Updated module is reloaded
  5. Routes are re-registered

This prevents:

  • duplicate routes
  • stale handlers
  • memory leaks

Middleware guards

Compose guards and pass combined state to handlers:

import { middleware, Action } from '@sourceregistry/sveltekit-service-manager';

const requireAuth = async ({ cookies }) => {
  const token = cookies.get('token');
  if (!token) throw Action.error(401, { message: 'Unauthorized' } as any);
  return { token };
};

export const service = {
  name: 'users',
  route: middleware(
    async ({ guard }) => Action.success(200, { token: guard.token }),
    requireAuth
  )
};

Internal service calls (no HTTP)

If a service defines local, you can call it directly:

import { Service } from '@sourceregistry/sveltekit-service-manager';

const value = Service('ping');

This is fully typed via App.Services.


Client-side usage

The client helper provides a typed, ergonomic way to call public services.

Basic usage

import {Service} from "@sourceregistry/sveltekit-service-manager";

const ping = Service('ping');

const result = await ping.call('/health');

With route helpers

ping.route('/health'); // "/api/v1/services/ping/health"

POST with JSON body

await ping.call('/echo', { message: 'hello' });

Client error handling

Errors throw a ServiceError:

try {
  await ping.call('/fail');
} catch (e) {
  if (e instanceof ServiceError) {
    console.error(e.code);     // HTTP status
    console.error(e.data);     // parsed JSON or text
  }
}

Custom entrypoint or fetch

Service('ping', {
  entryPoint: '/api/v1/services',
  executor: fetch
});

Supports dynamic [param] resolution using Page.params.


Express / Node middleware integration

You can run Express (or similar) inside a service:

import express from 'express';
import { Proxy } from '@sourceregistry/sveltekit-service-manager';

const app = express();
app.get('/hello', (_req, res) => res.json({ hello: 'world' }));

const proxy = new Proxy(app);

export const service = {
  name: 'express-demo',
  route: (event) => proxy.handle(event)
};

Exports

Server

  • ServiceManager
  • ServiceRouter / Router
  • Service (internal call)
  • Action
  • middleware
  • Server (WebHTTPServer)
  • Proxy (WebProxyServer)
  • json, text, html, file, fail, error

Client

  • Service
  • ServiceError
  • PublicServices

Testing

npm test

Tests live in tests/services.


License

Apache 2.0 see LICENSE