CLI • API
sv
sv exposes a programmatic API for creating projects and running add-ons.
defineAddon
Creates an add-on definition. See create your own for a full guide.
import { transforms } from '@sveltejs/sv-utils';
import { defineAddon, defineAddonOptions } from 'sv';
export default defineAddon({
id: 'my-addon',
options: defineAddonOptions().build(),
// called before run - declare dependencies, environment requirements, and dynamic options
setup: ({ dependsOn, unsupported, addOption, isKit }) => {
if (!isKit) unsupported('Requires SvelteKit');
dependsOn('eslint');
// dynamically add options based on workspace state or fetched data
addOption('theme', {
question: 'Which theme?',
type: 'select',
default: 'dark',
options: [{ value: 'dark' }, { value: 'light' }]
});
},
// the actual work — add files, edit files, declare dependencies
run: ({ sv, options, cancel }) => {
// add a dependency
sv.devDependency('my-lib', '^1.0.0');
// create or edit files using transforms from @sveltejs/sv-utils
sv.file('src/lib/foo.ts', (content) => {
return 'export const foo = true;';
});
sv.file(
'src/routes/+page.svelte',
transforms.svelte(({ ast, svelte }) => {
svelte.addFragment(ast, '<p>Hello!</p>');
})
);
// cancel at any point if something is wrong
// cancel('reason');
},
// displayed after the add-on runs
nextSteps: ({ options }) => ['Run `npm run dev` to get started']
});The sv object in run provides file, dependency, devDependency, and execute. For file transforms (AST-based editing of scripts, Svelte components, CSS, JSON, etc.) and package manager helpers, see @sveltejs/sv-utils.
Typed dynamic options
If your add-on adds options dynamically in setup (e.g. from a fetch), you can pass a type parameter to defineAddon to get strong typing for those options:
import { defineAddon, defineAddonOptions } from 'sv';
// cut
const addon = defineAddon<{ theme: string }>()({
id: 'my-addon',
options: defineAddonOptions().build(),
setup: ({ addOption }) => {
addOption('theme', {
question: 'Which theme?',
type: 'string',
default: 'dark'
});
},
run: ({ options }) => {
options.theme; // string
}
});The type parameter maps value types (boolean, string, number) to question definitions. Without it, defineAddon stays strict and only allows statically defined options.
defineAddonOptions
Builder for add-on options. Chained with .add() and finalized with .build().
import { defineAddonOptions } from 'sv';
const options = defineAddonOptions()
.add('database', {
question: 'Which database?',
type: 'select',
default: 'postgresql',
options: [
{ value: 'postgresql' },
{ value: 'mysql' },
{ value: 'sqlite' }
]
})
.add('docker', {
question: 'Add a docker-compose file?',
type: 'boolean',
default: false,
// only ask when database is not sqlite
condition: (opts) => opts.database !== 'sqlite'
})
.build();Options are asked in order. The condition callback receives the answers collected so far — return false to skip the question (its value will be undefined).
create
Programmatically create a new Svelte project.
import { create } from 'sv';
create({
cwd: './my-app',
name: 'my-app',
template: 'minimal',
types: 'typescript'
});add
Programmatically run add-ons against an existing project.
import { add, officialAddons } from 'sv';
await add({
cwd: './my-app',
addons: { prettier: officialAddons.prettier },
options: { prettier: {} },
packageManager: 'npm'
});