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

@founder-os/module-sdk

v0.1.1

Published

FounderOS module SDK — manifest types, validation schemas, and CLI checker

Readme

@founderos/module-sdk

v0.1.0 — the contract every uniqlabs module ships against. Use this to author a module that drops into uniqlabs-hub (the FounderOS marketplace runtime).

What's in the package

| Surface | Purpose | |---|---| | UniqlabsModuleManifest | TypeScript type for manifest.json — the rich shape used by MOD-001 (the canonical example). Required fields: id, name, version, category, description. | | ModuleManifest (legacy) | The original lighter-weight type. Kept for backwards compatibility — new modules should use UniqlabsModuleManifest. | | ModuleManifestSchema, validateManifest() | Zod schema + helper for runtime validation. Powers the validate-manifest CLI. | | ModuleDefinition, ModuleRegistry | Types the host uses to aggregate modules across all installed apps. | | resolveHostPackage(), resolveHostPackages(), hasFounderOSHost() | Generic dynamic-import helpers that gracefully degrade when @founderos/* packages aren't installed in the host. | | UniqlabsModuleLifecycle, defineLifecycle() | Optional lifecycle hook contract: onInstall, onUpgrade, onConfigChange, onUninstall. v0 ships the contract; the host's dispatcher lands Q2. | | validate-manifest (CLI) | npx validate-manifest .uniqlabs.modules/ — validates every manifest in a directory tree. |

How to author a uniqlabs module

A module is just a directory under .uniqlabs.modules/<id>/ containing at minimum:

.uniqlabs.modules/<id>/
├── manifest.json     # The contract — see UniqlabsModuleManifest
├── module.tsx        # Thin entrypoint, re-exports your root component
├── types.ts          # Module-local types (optional)
└── README.md         # What the module does (optional)

1. Write the manifest

{
  "$schema": "../../docs/uniqlabs-module-manifest.schema.json",
  "id": "fos-hiring-assistant",
  "name": "Hiring Assistant",
  "displayName": "founderOS Hiring Assistant",
  "version": "1.0.0",
  "sourceProduct": "hiring-assistant",
  "persona": "Recruiter",
  "category": "FOUNDER_OS_ZORD",
  "icon": "Briefcase",
  "description": "Founder-grade hiring pipeline...",
  "requiredFOSPackages": ["@founderos/database", "@founderos/auth"],
  "optionalFOSPackages": ["@founderos/event-bus"],
  "prismaModels": ["Candidate", "JobRequisition", "Interview"],
  "apiRoutes": [
    "GET /api/v1/copilot/positions",
    "POST /api/v1/copilot/positions"
  ],
  "components": ["HiringAssistantModule"],
  "configSchema": {
    "title": { "type": "string", "default": "Hiring Assistant", "description": "Card title" }
  },
  "backendRequirements": { "hasBackend": true, "backendType": "api-only" },
  "crossZordContext": {
    "publishes": ["candidate.applied", "hire.completed"],
    "consumes": ["calendar.events"]
  }
}

Validate it locally:

npx validate-manifest .uniqlabs.modules/fos-hiring-assistant/manifest.json

2. Write the host resolver

Modules that read host data (Prisma, NextAuth session, event bus) must never import @founderos/* packages at the top level — the host may not have them installed in every context (builder preview, standalone test, third-party host, ...). Use the SDK's resolver helpers:

// src/host-resolver.ts
import { resolveHostPackages } from '@founderos/module-sdk';

export async function loadHost() {
  const { auth, database } = await resolveHostPackages(['auth', 'database']);
  if (!auth || !database) return null; // standalone — caller falls back
  return { auth, database };
}

The resolver:

  • Builds the specifier at runtime so bundlers don't static-analyze the dynamic import
  • Returns null for any missing or failing package
  • Never throws

3. (Optional) Export lifecycle hooks

// src/lifecycle.ts
import { defineLifecycle } from '@founderos/module-sdk';

export const lifecycle = defineLifecycle({
  async onInstall(ctx) {
    ctx.log.info('Hiring Assistant installed for tenant', ctx.tenantId);
    // seed defaults, request OAuth scopes, etc.
  },
  async onUpgrade(ctx, prevVersion) {
    if (prevVersion === '0.9.x') { /* migrate */ }
  },
  async onConfigChange(ctx, next, prev) {
    if (next.enableAIScoring !== prev.enableAIScoring) {
      ctx.log.info('AI scoring toggled');
    }
  },
  async onUninstall(ctx) {
    ctx.log.info('Cleaning up tenant data');
  },
});

Every hook is optional. The host treats absent hooks as no-ops.

4. Submit to the host

  1. Drop your directory under .uniqlabs.modules/<id>/.
  2. Run the host's ingest script: npx tsx scripts/ingest-module.ts.
  3. The host validates the manifest, registers it in the builder palette, and updates src/modules/ingested-modules.generated.json.

Worked example — MOD-001 Hiring Assistant

The canonical reference implementation lives in uniqlabs-hub:

  • .uniqlabs.modules/hiring-assistant/manifest.json — the manifest
  • .uniqlabs.modules/hiring-assistant/module.tsx — entrypoint
  • .uniqlabs.modules/hiring-assistant/README.md — full walkthrough
  • src/modules/fos-hiring-assistant/host-resolver.ts — the pattern this SDK abstracts

The host's tests/modules/sdk-contract.test.ts runs the SDK's validateManifest() against the MOD-001 manifest to ensure the SDK + host stay in lock-step.

Versioning

| SDK version | Manifest schema | Notes | |---|---|---| | 0.1.0 | implicit v1 | Initial public surface. Manifest, host resolver, lifecycle hooks. |

Roadmap

| Wave | Item | |---|---| | Q1 (this release) | SDK v0 — types + resolver + lifecycle contract | | Q2 | Host dispatcher for lifecycle hooks · explicit schemaVersion field in manifest · third-party publisher onboarding · marketplace runtime (Wedge #3) | | Q3 | Versioned manifest migrations · sandboxing contract for third-party modules |

Internal

This package lives at packages/module-sdk/ inside the FounderOS monorepo. It's part of the pnpm workspace; consumers inside the monorepo import via @founderos/module-sdk.

For consumers outside the workspace (e.g. uniqlabs-hub, which is an independent npm package), see the host-side wire-up doc: docs/MODULE_SDK.md.