Skip to content

extensiondev/urls

Repository files navigation

@extension.dev/urls Version Downloads Discord

One source of truth for the origins and route paths that link the extension.dev fleet together.

Logo

Why one package for links

A cross-app link is two halves: the host (which app) and the path (which route inside it). Hardcode either and the day an app moves or a route is renamed, every caller drifts. This package keeps both halves in one place so a link a tool hands back can never point at a route the app router no longer serves.

  • @extension.dev/urls/paths - pure, environment-free route builders. Safe to call from any runtime (Next.js, Vite SPAs, Node, the bundled MCP) because they read no environment and only encode path shapes.
  • @extension.dev/urls/origins - the host resolver. Each runtime names its env vars differently, so this module never reads the environment itself: the caller passes in whatever overrides it has and gets back a full origin set, with local-dev hosts derived from the Caddy proxy map when the environment looks local, and production hosts otherwise.
  • @extension.dev/urls/userland - whole-URL builders for the public build viewer. userland is the one app whose production host is per-workspace (<workspace>.extension.dev), so its two halves cannot be chosen independently and it gets its own module rather than a paths entry.

Install

npm install @extension.dev/urls

Usage

import { resolveOrigins } from "@extension.dev/urls/origins";
import { consoleProjectPath, ConsoleProjectPage } from "@extension.dev/urls/paths";

const origins = resolveOrigins({
  // Pass only the vars this runtime actually has; the rest derive.
  www: process.env.EXTENSION_DEV_API_URL,
});

// A full link is `origins.<app> + <pathBuilder>(...)`.
const buildsUrl =
  origins.console +
  consoleProjectPath({ workspace: "acme", project: "toolbar" }, ConsoleProjectPage.builds);

Set a single local override and every unset origin follows it to the dev proxy:

resolveOrigins({ www: "http://localhost:3100" }).console;
// -> "http://console.extension.localhost"

The public build viewer takes whole URLs, because the workspace lives in the host in production and in the path locally:

import { userlandBuildUrl } from "@extension.dev/urls/userland";

userlandBuildUrl({ workspace: "acme", project: "toolbar" }, "abc1234");
// -> "https://acme.extension.dev/toolbar/builds/abc1234"

userlandBuildUrl({ workspace: "acme", project: "toolbar" }, "abc1234", {
  base: resolveOrigins({ www: "http://localhost:3100" }).userland,
});
// -> "http://userland.extension.localhost/acme/toolbar/builds/abc1234"

The extension.dev stack

Package Use it to
@extension.dev/mcp Give an AI agent hands: scaffold, run, inspect, and publish extensions
@extension.dev/skill Teach agents the judgment half: cross-browser rules, gotchas, playbooks
@extension.dev/deploy Ship to the Chrome, Firefox, and Edge stores from CI or a terminal
@extension.dev/artifact-integrity Verify artifacts and gate CI on tampered bytes before they ship

All of it rides on Extension.js, the open-source cross-browser extension framework.

Community

  • Join the Discord for help and feedback
  • Browse production-ready examples
  • Report Extension.js framework issues on GitHub

License

Apache-2.0. See LICENSE and NOTICE.

About

One source of truth for cross-app origins and route paths across the extension.dev fleet.

Resources

Security policy

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages