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

@gadicc/loom

v1.31.1

Published

Deno-first shared helpers for extracting common Next.js app code.

Readme

loom

Deno-first shared helpers for extracting common code from multiple Next.js apps.

This repo currently still lives in the gadicc directory, but the package name is @gadicc/loom and the intended CLI name is loom.

Project status and support

Loom is primarily developed for the maintainer's own commercial and open source applications. Others are welcome to use it, but it is provided without warranty and without any commitment to support, compatibility, maintenance periods, or a particular roadmap. Releases follow semantic versioning so independently pinned consumer apps can upgrade deliberately.

Security issues should be reported privately as described in SECURITY.md, not through a public issue.

Current feature set:

  • shared DB stack scaffolding for Neon/Drizzle/Valibot/PGlite consumers
  • shared jobs framework primitives for app-local src/jobs implementations
  • shared Next.js App Router jobs adapters for list pages, run pages, and route handlers
  • auditable, scope-agnostic API-key authorization with an app-owned Better Auth adapter, managed audit schema, explicit jobs integration, optional MUI UI, Vercel country/IP snapshots, and bounded retention
  • durable provider-neutral outgoing mail with atomic outbox leases, Postal transport and signed webhooks, per-recipient state, and admin-gated test mail
  • a Loom-managed env runner for non-Next commands that need the same .env* semantics as Next
  • consumer project tooling that supports package.json, deno.json, deno.jsonc, and dual-config projects with separate task and dependency owners recorded in loom.json
  • Deno tests with BDD-style assertions
  • npm package generation via dnt

License

Copyright © 2026 Gadi Cohen. Licensed under the Apache License 2.0.

The license includes warranty disclaimers and a limitation of liability; consumers remain responsible for determining whether Loom is appropriate for their applications.

Loom does not redistribute third-party agent skills. Its metadata-only catalog records reviewed upstream revisions and license evidence; consumer projects choose and cache the corresponding content directly from upstream.

Public npm package

Loom's public distribution is @gadicc/loom on npm:

pnpm add @gadicc/loom
# or: npm install @gadicc/loom

Consumer projects do not need registry mappings or package-read tokens.

Maintainer bootstrap, trusted-publisher configuration, release verification, and consumer migration are documented in docs/npm-publishing.md.

CLI

loom now includes a small bootstrap CLI and feature-scaffolding entrypoint. The detection, dual-config precedence, and safe task-composition contract is documented in docs/project-tooling.md.

  • loom init adds @gadicc/loom to the authoritative dependency config, creates or updates loom.json, records the authoritative task runner/config and dependency manager/config, refreshes the managed Loom bootstrap block in AGENTS.md, and ensures the managed .agents/skills/* links point at the installed @gadicc/loom package, activates skills exposed by installed npm packages, and configures version-matched Next.js guidance when supported by the installed Next version.
  • loom add lists the shared features that the CLI can activate and shows a short description for each one.
  • loom add <feature> activates one shared feature in loom.json and applies that feature's scaffolding without overwriting app-local wrappers.
  • loom add auth records app-owned Better Auth entrypoints, scaffolds missing thin client and route wrappers, and enables the loom-auth skill link.
  • loom add jobs activates the shared jobs feature in loom.json and scaffolds any missing local jobs/admin route files without overwriting existing app-local wrappers, while also enabling the loom-jobs skill link.
  • loom add db activates the shared DB feature in loom.json, adds the managed DB dependencies and tasks to their recorded configs, rewrites the standard neon.ts / neonFull.ts / drizzle.config.ts / PGlite test harness files into Loom-managed thin wrappers, scaffolds the app-local fixture script entrypoint, and enables the loom-db skill link. neonFull verifies remote TLS certificates and hostnames even when the selected URL contains sslmode=require. Private remote CAs must be trusted explicitly, for example with process-start NODE_EXTRA_CA_CERTS; invalid certificates fail instead of falling back. The existing plaintext exceptions for db.localtest.me, localhost and 127.0.0.1 remain, including their existing override of URL TLS settings. Database URL precedence is unchanged. TLS verification does not add SCRAM channel-binding support to the underlying driver. Remote IPv4 certificates must contain a matching IP subject alternative name. DNS-only multi-host URLs retain the driver's per-host verification. Empty or escaped hosts, extra unescaped @ signs or fragments in the authority, IP-containing multi-host URLs and bracketed IPv6 hosts are rejected because the runtime cannot reliably bind their current driver routing to certificate identity; use an explicit DNS host or single IPv4 address.
  • loom add files activates the shared files schema contract after the DB feature is active. It materializes the Loom-managed Drizzle schema blueprint into an app-local committed schema file, records the blueprint version and hash in loom.json, scaffolds app-local repository/storage/access/route files, and leaves migration generation to the app's normal db:generate review flow.
  • loom add mail requires active DB and auth features, materializes the message/delivery/event Drizzle schema, and scaffolds a working app-local repository, Postal transport, service, RSA-signed webhook route, fail-closed admin boundary, and (for MUI apps) mail log plus test/one-off-mail UI. When jobs is active it also scaffolds a drain job without rewriting app-owned catalogs or schedules. Loom never generates the migration.
  • @gadicc/loom/mail owns provider-neutral enqueue/lease/retry/cancel/event orchestration and memory test adapters. @gadicc/loom/mail/postal owns the Postal HTTP and webhook contract, @gadicc/loom/next/mail owns the raw-body route handler, and @gadicc/loom/mui/mail owns optional serializable admin views. Keep the default sender structured with the required bare address [email protected] and optional display name POSTAL_FROM_NAME=Example App. Configure Postal webhook verification with a JSON array of RSA public JWKs in POSTAL_WEBHOOK_PUBLIC_KEYS; shared-secret emulation is unsupported.
  • loom files r2 setup creates or reuses private Cloudflare R2 buckets for Production and Preview, records the explicit Cloudflare account and storage policy in loom.json, replaces only the untouched generated storage stub, configures canonical FILES_S3_* values in Vercel, and configures local MinIO in .env.local by default. Use --local-provider r2 for deliberately shared development storage or --local-provider none to leave local storage unwired. Existing custom storage modules and credentials are preserved.
  • loom files r2 check verifies the selected Cloudflare account, bucket existence and private access, exact non-secret Vercel values in Production and Preview, the absence of Files credentials in Vercel Development, and the configured local MinIO endpoint/bucket. The same checks run through loom check --network.
  • loom add api-keys requires active auth and DB features, materializes the versioned audit schema, scaffolds fail-safe policy/verifier/repository/action boundaries and user/admin pages, and links the loom-api-keys skill. It does not authorize existing routes, change jobs, or generate migrations.
  • @gadicc/loom/apiKeys provides typed scope registries, exact-match policy dispatch, credential extraction, fingerprints, authorization/audit contracts, country normalization, and bounded audit retention. @gadicc/loom/next/apiKeys adds App Router authorization, session-or-key composition, completion auditing, and explicit Vercel request context. @gadicc/loom/mui/apiKeys provides optional lifecycle and audit UI.
  • loom api-keys integrate jobs --resource <name> --action <name> records an explicit additive jobs authorization integration after the app has protected its HTTP jobs route with fresh session/admin policy. Direct local runners are unchanged and remain API-key-free.
  • loom api-keys retention enable records the default 180-day/5,000-request retention policy. The app must transactionally implement the retention repository and schedule the shared runner; Loom does not silently create or modify jobs. Use retention disable for an app-owned legal-hold workflow.
  • @gadicc/loom/files provides the shared files runtime primitives: SHA-256 hashing, digest verification, metadata detection, repository/storage adapter contracts, in-memory test adapters, and headless upload helpers.
  • @gadicc/loom/files/s3 adapts an app-provided AWS SDK v3 S3 client to the shared storage contract without making AWS SDK packages Loom dependencies.
  • @gadicc/loom/next/files provides App Router route-handler factories for uploads, metadata lookup, and downloads over app-provided persistence and storage adapters.
  • loom add lingui adopts Lingui catalog tooling without owning locale routing or translations. It records loader versus precompile mode, adds compatible dependencies and extract/compile tasks, ignores generated JavaScript catalogs, and ensures precompiled catalogs are built before the app build. loom check also reports tracked generated catalogs, task-order drift, mismatched runtime imports, and missing Next.js loader/SWC wiring.
  • loom add pwa activates the shared Serwist PWA feature, adds the Serwist dependencies and build task, safely composes it after an existing Next build, scaffolds configurator-mode serwist.config.mjs plus worker/provider files, records whether the update prompt should use the MUI adapter or browser fallback, adds a 60-second update check interval for MUI installs, and ignores generated service-worker output.
  • loom add skills adopts matching reviewed external skills into the gitignored .loom/skills cache, records exact revisions and content hashes in loom-skills.lock.json, and activates package-provided skills.
  • loom status summarizes the installed Loom package, loom.json state, active features, local-dev sync state, and managed/recommended skill links.
  • loom env -- <command> [...args] loads the consumer project .env* files with Next-compatible @next/env semantics, preserves existing shell env precedence, then runs the command from the consumer project root. Use it for non-Next commands such as direct job runners, Drizzle, ad hoc DB inspection, and app scripts that need env. Next commands such as next dev and next build already load .env* themselves.
  • loom skills check validates the project lock, external cache, and activation links.
  • loom skills update updates adopted external skills to Loom's current reviewed immutable revisions.
  • loom skills disable <name> opts out of automatic activation; enable clears the opt-out and sync reactivates the skill.
  • loom db fixtures runs the Loom-managed DB fixture dump entrypoint for the active DB feature, using the configured scripts/dump-test-tables.ts and scripts tsconfig.
  • loom db schema-gen runs the Loom-managed vs_tocode workflow for the active DB feature and then refreshes the Valibot barrel file. Pass extra generator flags after --, for example loom db schema-gen -- --watch.
  • loom db schemas sync re-materializes active Loom-managed schema blueprints into app-local schema files only when the file still matches the last recorded Loom hash. It refuses to overwrite local edits, updates simple schema barrel exports, and never generates Drizzle migrations.
  • loom db neon setup provisions a Vercel-managed Neon database for the active DB feature, connects it to the linked Vercel project for Production and Preview only, skips local env pulling, and records the provider policy in loom.json.
  • loom db neon check runs only the DB/Neon network checks: Vercel CLI availability, project linking, Neon resource connection, Production/Preview DB env vars, and the absence of DB env vars in Development.
  • loom db release setup-github creates/updates the GitHub production environment for staged Vercel releases: it stores VERCEL_ORG_ID and VERCEL_PROJECT_ID, and saves a bounded project-scoped Vercel token as the GitHub VERCEL_TOKEN environment secret. Reruns preserve an existing secret; use --rotate-token for explicit replacement or --token-scope team only for compatibility. Its branch policy and the release checks use features.db.config.release.productionBranch from loom.json, defaulting to main. See release configuration for other production branches and matching app-owned workflow/Vercel settings.
  • loom db release prepare-vercel-project production <env> <metadata> <project> materializes a private, consistency-checked Production env snapshot and exact .vercel/project.json for a project-scoped token. After a standalone build, stage the prebuilt artifact with VERCEL_ORG_ID and VERCEL_PROJECT_ID removed from that deploy process, then use loom db release promote-vercel <deployment-id> for bounded project API promotion and terminal readback.
  • loom dev local /path/to/loom enables local unpublished Loom development. It adds a managed file: override in pnpm-workspace.yaml for pnpm projects or a Deno links entry in deno.json(c), then runs the local-dev sync flow when needed.
  • loom dev sync rebuilds the local Loom package when source files are newer than the generated npm output, then refreshes the consuming app with the pnpm update/install flow or deno install when the installed linked dependency is stale. Other Loom commands also run this sync automatically when the managed local-dev override is active; pass --no-sync to skip it. Each sync records the Loom source commit in the managed pnpm-workspace.yaml block and gitignored .loom/dev-state.json when the local package path points at a Loom git checkout.
  • loom dev published removes that managed local-dev override so the app can return to the published package version. When a prior sync recorded a Loom source commit, this command verifies that the commit is reachable from origin/main and either included in a semver release tag or package-equivalent to the latest semver release because only non-package files changed after that tag. It then switches the app to the exact published @gadicc/loom version that covers the sync. If no recorded commit exists, the command preserves the older compatibility behavior and switches back to the existing published dependency with an explicit warning. The command also notices stale lockfiles that still resolve Loom to a local package even after the workspace override has been removed.
  • loom check verifies the recorded package/Deno configs, loom.json, the managed AGENTS.md block and .agents/skills/* links, and then runs feature-specific checks for active entries in loom.json, including jobs-wrapper validation plus DB runtime, script, Valibot-barrel wiring, and the production migration release flow for active DB installs, managed local schema validation for active files installs, and Serwist package, worker, provider, update-check interval, MUI-confirm, and build-script wiring for active PWA installs. The DB release-flow check expects Vercel automatic production Git deployments to be disabled in vercel.json and a GitHub Actions workflow to pull Vercel production settings, build, upload a staged prebuilt production deployment, run a live migration credential preflight, run db:migrate against the preserved production environment, then promote the staged deployment. loom check --network also verifies the required GitHub release secret/variables when that workflow exists. When .github/workflows/*.yml|yaml still contains Loom's obsolete GitHub Packages registry/auth setup, loom check recommends removing it. The command also activates newly discovered npm package skills with a notice, warns when the managed local dev override is active, reports inline dotenv/@next/env imports or DB/jobs tasks that bypass loom env --, warns when authoritative and secondary configs expose conflicting tasks, and warns when a Deno link or pnpm-lock.yaml still resolves Loom to local source. If .loom/dev-state.json records a synced Loom commit, loom check also explains whether that commit is unpublished or published in a newer exact Loom version than the app is pinned to. Pass --strict-skills to turn missing skill recommendations into check failures. Pass --production to make local Loom dev overrides, local lockfile resolutions, unresolved synced Loom commits, and DB migration release-flow gaps release-blocking failures. Pass --network to also run registered feature network checks after the local project checks.

The current CLI scope is project bootstrap, validation, and feature-specific scaffolding. Extracted feature hooks are added behind the same init, add, feature subcommand, and check flows.

Consumer app release workflow

Consumer apps may stay in local Loom development mode during normal feature work:

loom dev local /home/dragon/www/npm/loom
loom dev sync
loom check

Before pushing or releasing a consumer app, switch back to the published Loom package and run the production gate:

loom dev published
pnpm update --no-save @gadicc/loom@<version-from-loom-output>
pnpm install
loom check --production

For Deno-managed projects, replace the pnpm refresh commands with deno install; loom dev published prints the project-appropriate command.

Publishing Loom is only required when the app was synced against package-relevant Loom changes that are not already covered by a published semver tag. Publishing a new Loom version does not move other consumer apps; each app remains on its committed dependency config and lockfile until that app deliberately upgrades.

New app DB bootstrap

For a new Vercel app that needs the shared DB stack:

loom init
loom add db
vercel link
loom db neon setup
loom check --network

loom db neon setup runs the Vercel Marketplace install through the Vercel CLI using Production and Preview environments only. It intentionally avoids Development and uses --no-env-pull so local .env* files are not populated by the integration. Pass --name <resource-name> to override the default <project>-db resource name, --region <region> to select a supported Neon Marketplace region such as sin1, or --plan <plan-id> if a new Marketplace installation requires a specific plan id. When Neon is already installed for the team, Loom omits --plan and preserves that installation's current plan. Neon Auth is explicitly disabled by default because Loom's auth feature uses Better Auth; pass --neon-auth only when the app intentionally wants Neon Auth too.

Network checks are line-based for now so they remain readable in CI logs:

[1/6] Checking Vercel CLI is available ......................... ok ✓
      Using vercel.
[2/6] Checking Project is linked to Vercel ..................... ok ✓
      Linked to Vercel project prj_...

When stdout is an interactive terminal, Loom uses an updating progress line with a progress bar and prints only problem checks at the end. This is disabled automatically in CI and can be disabled explicitly with --no-progress. Use --no-color to disable colored status output.

See docs/network-checks.md for the hook design and future expansion notes.

AI skills

The package now publishes Codex skill folders under skills/.

  • skills/loom provides global loom guidance for consumer apps, centered on loom.json, feature activation, shared-vs-local ownership boundaries, and a small set of shared consumer-repo policies such as verification, documentation/comments, and commit-message expectations. Consumer repos keep AGENTS.md small and use a managed Loom block there to route work into this shared skill.
  • skills/loom-torvalds-review adapts the external linus-torvalds-skill review method to web apps, shared packages, CLI code, native code, and explicit prototypes. It keeps the upstream emphasis on correctness, compatibility, evidence, and simplicity while disabling literal kernel/C rules outside their real prerequisites.
  • skills/upgrade-deps provides a staged Deno and JavaScript/TypeScript dependency-upgrade workflow covering compatibility groups, rollback safety, failure isolation, major migrations, reviewable commits, and exact-tree final verification.
  • skills/modernize-app guides staged modernization of an existing application, including identity/data preservation, optional offline/media transitions and verified rollout. Dependency-only work stays with upgrade-deps; new apps use scaffolding rather than this migration workflow.
  • skills/loom-db provides DB-feature guidance for Neon/Drizzle wiring, managed local schema blueprints, Valibot generation, and the shared PGlite harness.
  • skills/loom-auth covers Better Auth secrets, rotation, environment trust boundaries, and proxy-aware localhost OAuth configuration.
  • skills/loom-jobs provides jobs-feature guidance for app-local catalogs, admin route wrappers, and shared helper wiring.
  • skills/loom-api-keys provides API-key adoption, authorization, audit, Vercel geolocation, UI mapping, jobs integration, and retention guidance.

Projects do not need to copy these files manually. loom init, loom add db, loom add jobs, and loom check manage a small project-local AGENTS.md Loom block plus .agents/skills/* symlinks that point to the installed node_modules/@gadicc/loom/skills/* folders. The global loom, loom-torvalds-review, upgrade-deps, and modernize-app skills are linked for every initialized project; feature skills are linked when their matching feature is active.

Third-party skills are not packaged with Loom. Loom carries a metadata-only catalog containing source URLs, immutable commits, content hashes, and license evidence. loom add skills installs applicable reviewed skills directly into a consumer project's gitignored .loom/skills cache and records the selection in the committed loom-skills.lock.json. Missing or unclear licenses require the explicit --accept-unknown-license <name> flag. loom skills migrate replaces legacy symlinks from older Loom releases, while preserving custom local skill directories.

Loom also scans installed npm packages for a root SKILL.md, skills/*, or .agents/skills/*. New package-provided skills are activated automatically by loom init, loom skills sync, and ordinary loom check, with a notice that includes loom skills disable <name> as the opt-out path.

For local Loom package development, prefer loom dev local and the managed file: marker flow over pnpm link. loom dev sync owns the rebuild and pnpm refresh step for that local package. When it refreshes the installed package at the start of another Loom command, rerun that original command so the current process uses the refreshed CLI code. This keeps the committed dependency on the published version while still resolving peer dependencies correctly during local development. Treat this as a workaround for current pnpm behavior rather than a permanent preference; if pnpm's local-link behavior changes, this flow can be simplified or removed later.

The managed local-dev block also records the Loom source commit that was synced when the local package path points at a Loom git checkout, and the same state is persisted in gitignored .loom/dev-state.json so Loom can still diagnose stale local lockfiles after the workspace override has been removed. loom dev published uses that record as a release gate: clean commits that have reached origin/main and are either included in a semver release tag or have no package-relevant changes after the latest semver tag can be switched to the exact published version, while dirty or unreleased package changes block the switch. Existing apps with older local-dev blocks that lack this metadata can still switch back to their current published dependency, but new syncs should be used before relying on the release gate.

Loom's external catalog currently recommends these defaults:

  • ai-sdk
  • find-skills
  • frontend-design
  • linus-torvalds-skill (with Loom's context-aware review companion)
  • vercel-composition-patterns
  • vercel-react-best-practices

It adds these dependency-matched recommendations:

  • better-auth-best-practices for projects that depend on Better Auth packages
  • pnpm for projects that use pnpm
  • vitest for projects that use Vitest

Next.js is handled separately because current Next releases ship documentation matching the installed framework version under node_modules/next/dist/docs. Loom adds a managed AGENTS.md pointer to those docs. Older Next releases can use the official npx @next/codemod@latest agents-md fallback; migration removes the retired next-best-practices symlink.

See docs/project-skills.md for lock/cache semantics, package discovery, opt-outs, collision behavior, and migration details.

Jobs framework

The shared jobs code is designed so each app keeps its own jobs in src/jobs/*.ts, while the shared package owns the common controller, catalog, execution, formatting, and direct-run helpers. Keep metadata in a dependency-free module and use createLazyJob in the executable catalog so constructing an HTTP or direct-run catalog does not initialize every job's transitive dependencies.

Example app-local job:

import type { Job } from "@gadicc/loom/jobs";
import { testMeta as meta } from "./indexWithMetaOnly";

export { meta };

export const handler: Job["handler"] = async (job) => {
  job.log("hello");
};

Example dependency-free metadata and lazy catalog entry:

// indexWithMetaOnly.ts
import type { Job } from "@gadicc/loom/jobs";

export const testMeta: Job["meta"] = {
  id: "test",
  desc: "Example job",
};

// index.ts
import { createLazyJob } from "@gadicc/loom/jobs";
import { testMeta } from "./indexWithMetaOnly";

export const test = createLazyJob(testMeta, () => import("./test"));

Job output can be sanitized once at the execution boundary so the same policy applies to NDJSON, text, HTML, direct runners, HTTP responses, and app-provided formatters:

import { createJobOutputRedactor, type Job } from "@gadicc/loom/jobs";
import { createJobsRouteHandler } from "@gadicc/loom/next/jobs/route";

const providerToken = process.env.PROVIDER_TOKEN;
if (!providerToken) throw new Error("PROVIDER_TOKEN is required");

const outputSanitizer = createJobOutputRedactor(
  new Map<string | RegExp, true | string>([
    [providerToken, true],
    [/Bearer\s+\S+/gi, "Bearer [REDACTED]"],
  ]),
);

export const jobsRouteHandler = createJobsRouteHandler({
  catalog: jobs as readonly Job[],
  handlerErrorMessage: "Job execution failed.",
  outputSanitizer,
});

Redaction rules run in map insertion order, each against the preceding rule's result. Exact strings match wherever they occur. RegExp rules replace every match without using the caller's lastIndex, even when the expression is non-global or sticky. A true replacement means [REDACTED]; string replacements are literal, so $&, $1, and $$ are not expanded. Empty exact matchers are rejected without printing configured match or replacement values.

The sanitizer visits every string value emitted through job.log(), all other log levels, and job.json() while retaining normal JSON behavior for arrays, objects, dates, numbers, booleans, and null. Inputs are not mutated. If a sanitizer throws or returns a non-string, Loom fails the execution closed and emits only Job output sanitation failed. for that failure.

Output redaction and unexpected-error disclosure are separate. Omitting handlerErrorMessage retains Loom's existing full-stack fatal event; supplying a string emits that exact generic literal instead. Deferred-task errors keep their own deferredTaskErrorHandler, and the additive runDeferredTasksWithResult() method returns a failure count while runDeferredTasks() keeps its legacy Promise<void> contract. Consumers that run deferred tasks inline can emit a generic event from that callback; tasks run after a response stream closes should report through a separate safe sink. cancellationMessage: false suppresses the legacy Job cancelled event when cancellation must only set the controller flag.

This boundary protects Loom job-event output only. It does not sanitize console.*, provider or framework logs, audit metadata, request URLs, thrown values retained in execution.result, or external logging systems. Object property names are JSON structure rather than string values and are not rewritten; do not place secrets in keys.

For the strongest Next.js deployment boundary, mount jobs in static route files with createJobRouteHandler({ job }). A dynamic [id] route is one serverless function and therefore still traces every implementation reachable from its catalog, even when createLazyJob prevents unrelated modules from evaluating at runtime.

Loom can manage those file-based entrypoints from the Jobs config in loom.json:

{
  "staticRoutes": {
    "handlerFactoryExport": "createHttpJobRouteHandler",
    "jobs": {
      "example": "@/jobs/example",
      "short-example": {
        "module": "@/jobs/short-example",
        "maxDuration": 300
      }
    },
    "maxDuration": 1800,
    "routeDirectory": "src/app/admin/jobs"
  }
}

Run loom add jobs after changing the map. Loom creates, updates, and removes only wrappers bearing its managed marker; an existing unmanaged route is preserved and reported. loom check verifies the generated set and its direct literal maxDuration exports. The default is Vercel's current 30-minute maximum of 1800, while staticRoutes.maxDuration and each job's optional maxDuration override keep shorter limits explicit and checkable.