jsrepo.config
The configuration file for jsrepo.
The jsrepo.config.(ts|js|mts|mjs) file is used to configure jsrepo projects and registries.
Having a js based config allows you far more flexibility when configuring your project or registry allowing you to abstract out the reusable parts of your config.
Creating a config
To create a new config in your project you can run the following command or copy the code below:
jsrepo initThis will initialize a blank config in your project.
import { defineConfig } from "jsrepo";
export default defineConfig({
// configure where stuff comes from here
registries: [],
// configure where stuff goes here
paths: {},
});We default to .mts to prevent errors when you don't have "type": "module" in your package.json. But you can
rename this to .ts if you prefer.
Create with a registry
To create your config with a registry you can run the following command:
jsrepo init [registry]Let's look at an example...
You might run:
jsrepo init https://example.com/registryFirst you will be prompted to install any plugins specified by the registry author:
┌ jsrepo
│
◆ Would you like to add the @jsrepo/transform-prettier transform plugin?
│ ● Yes / ○ NoNext you can configure the paths for the items you want to add. (These are the types of the items you can add from the registry)
◆ Which paths would you like to configure?
│ ◻ block (Default: src/components)
│ ◻ component
│ ◻ lib
└Once you have configured the paths any items that were specified by the registry author to add upon initialization will be added to your project. And the resulting config should look like this:
import { defineConfig } from "jsrepo";
import prettier from "@jsrepo/transform-prettier";
export default defineConfig({
registries: ["https://example.com/registry"],
transforms: [prettier()],
paths: {
block: "src/components",
component: "src/components/ui",
lib: "src/lib",
},
});Adding plugins
Plugins are a big part of what makes jsrepo so powerful but having to manually add them to your config kinda sucks. So we've added a way to automatically install and add plugins to your config.
To add a plugin run the following command:
# add a transform plugin
jsrepo config transform @jsrepo/transform-prettier
# add a provider plugin
jsrepo config provider jsrepo-provider-<provider>
# add a language plugin
jsrepo config language jsrepo-language-<language>This will automatically install the plugin and add it to your config:
import { defineConfig } from "jsrepo";
import prettier from "@jsrepo/transform-prettier";
export default defineConfig({
registries: ["https://example.com/registry"],
transforms: [prettier()],
paths: {
block: "src/components",
component: "src/components/ui",
lib: "src/lib",
},
});As your config grows this will continue to work (so long as you don't use some really contrived syntax for your config).
Options
languages
Languages are how jsrepo knows how to parse and transform code. You can read more about the supported languages here.
import { defineConfig } from "jsrepo";
import { js } from "jsrepo/languages";
export default defineConfig({
languages: [js()],
});paths
Paths are how jsrepo knows where to put items in your project. Paths can either reference a type of item or a specific item.
import { defineConfig } from "jsrepo";
export default defineConfig({
paths: {
block: "src/components",
// control where a specific item goes by referencing it by `<type>/<name>`
"ui/button": "src/components/ui/button",
},
});providers
Providers are how jsrepo knows where to fetch items from. You can read more about providers here.
import { defineConfig } from "jsrepo";
import { fs } from "jsrepo/providers";
export default defineConfig({
providers: [fs()],
});registries
Registries are the default locations that items will be fetched from when you run jsrepo commands.
import { defineConfig } from "jsrepo";
export default defineConfig({
registries: ["https://example.com/registry"],
});registry
The registry option allows you to define your own registry or registries. You can learn more about creating your own registry here.
import { defineConfig } from "jsrepo";
export default defineConfig({
registry: ...,
});transforms
Transforms allow you to make modifications to code before it is added to your project this is where you might add formatting, and other code modifications. You can read more about transforms here.
import { defineConfig } from "jsrepo";
import prettier from "@jsrepo/transform-prettier";
export default defineConfig({
transforms: [prettier()],
});onwarn
Deprecated: The top-level onwarn option is deprecated. Use build.onwarn instead.
build.onwarn
The build.onwarn option allows you to customize how warnings are handled during the build process. You can suppress specific warnings, transform them, or use the default logging behavior.
The handler receives two arguments:
warning: The warning instance (extends the baseWarningclass)handler: A function to log the warning using the default format
import { defineConfig } from "jsrepo";
import { InvalidImportWarning, LanguageNotFoundWarning } from "jsrepo/warnings";
export default defineConfig({
// ...
build: {
onwarn: (warning, handler) => {
// Suppress warnings for SvelteKit internal imports
if (warning instanceof InvalidImportWarning) {
if (['$app/server', '$app/navigation'].includes(warning.specifier)) {
return; // Don't log this warning
}
}
// Suppress language warnings for specific file types
if (warning instanceof LanguageNotFoundWarning) {
if (warning.path.endsWith('.glb') || warning.path.endsWith('.png')) {
return; // Don't log this warning
}
}
// Log all other warnings using the default handler
handler(warning);
},
},
});Available warning types:
InvalidImportWarning: Triggered when an import is skipped because it's not a valid package name or path aliasLanguageNotFoundWarning: Triggered when a language cannot be found to resolve dependencies for a fileUnresolvableDynamicImportWarning: Triggered when a dynamic import cannot be resolved due to unresolvable syntax
All warnings extend the base Warning class which has a message property. Each specific warning type includes additional properties relevant to that warning type.
build.remoteDependencyResolver
The build.remoteDependencyResolver option lets you rewrite each detected remote dependency before it is added to the built registry output.
This is useful when your source package.json uses version protocols like workspace:* or catalog: and you want to replace them with concrete versions during build.
For pnpm workspaces (workspace and catalog protocols), use @jsrepo/pnpm:
import { defineConfig } from "jsrepo";
import { pnpm } from "@jsrepo/pnpm";
export default defineConfig({
build: {
remoteDependencyResolver: pnpm(),
},
});For bun workspaces, use @jsrepo/bun:
import { defineConfig } from "jsrepo";
import { bun } from "@jsrepo/bun";
export default defineConfig({
build: {
remoteDependencyResolver: bun(),
},
});Or implement a custom resolver:
import { defineConfig } from "jsrepo";
export default defineConfig({
build: {
remoteDependencyResolver: async (dep) => {
if (dep.version === "workspace:*") {
return { ...dep, version: "1.2.3" };
}
if (dep.version === "catalog:") {
return { ...dep, version: "^4.0.0" };
}
return dep;
},
},
});hooks
Hooks allow you to run custom logic before and after CLI commands.
beforehooks run before the command executes.afterhooks run after the command completes.
Hooks can be a function, a shell command string, or an array of either.
import { defineConfig } from "jsrepo";
export default defineConfig({
hooks: {
before: ({ command }) => {
console.log(`Running ${command}...`);
},
after: "echo done",
},
});Function hooks receive typed arguments with a command discriminant. Use it to narrow and access command-specific data:
import { defineConfig } from "jsrepo";
export default defineConfig({
hooks: {
after: (args) => {
if (args.command === "add") {
console.log(`Added ${args.result.items.length} items`);
}
},
},
});You can also use an array of hooks:
import { defineConfig } from "jsrepo";
export default defineConfig({
hooks: {
before: [
({ command }) => console.log(`Starting ${command}...`),
"echo 'before hook done'",
],
},
});