Skip to main content

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 { import transformstransforms } from '@sveltejs/sv-utils';
import { function defineAddon<const Id$1 extends string, Args extends OptionDefinition>(config: Addon<Args, Id$1>): Addon<Args, Id$1>

The entry point for your addon, It will hold every thing! (options, setup, run, nextSteps, ...)

defineAddon
, function defineAddonOptions(): OptionBuilder<{}>

Options for an addon.

Will be prompted to the user if there are not answered by args when calling the cli.

const options = defineAddonOptions()
  .add('demo', {
	question: `demo? ${color.optional('(a cool one!)')}`
	type: string | boolean | number | select | multiselect,
	default: true,
  })
  .build();

To define by args, you can do

npx sv add <addon>=<option1>:<value1>+<option2>:<value2>
defineAddonOptions
} from 'sv';
export default defineAddon<"my-addon", {}>(config: Addon<{}, "my-addon">): Addon<{}, "my-addon">

The entry point for your addon, It will hold every thing! (options, setup, run, nextSteps, ...)

defineAddon
({
id: "my-addon"id: 'my-addon', options: {}options: function defineAddonOptions(): OptionBuilder<{}>

Options for an addon.

Will be prompted to the user if there are not answered by args when calling the cli.

const options = defineAddonOptions()
  .add('demo', {
	question: `demo? ${color.optional('(a cool one!)')}`
	type: string | boolean | number | select | multiselect,
	default: true,
  })
  .build();

To define by args, you can do

npx sv add <addon>=<option1>:<value1>+<option2>:<value2>
defineAddonOptions
().function build(): {}

Finalize all options of your add-on.

build
(),
// called before run — declare dependencies and environment requirements
setup?: ((workspace: Workspace & {
    dependsOn: (name: keyof OfficialAddons) => void;
    unsupported: (reason: string) => void;
    runsAfter: (name: keyof OfficialAddons) => void;
}) => MaybePromise<...>) | undefined

Setup the addon. Will be called before the addon is run.

setup
: ({ dependsOn: (name: keyof OfficialAddons) => void

On what official addons does this addon depend on?

dependsOn
, unsupported: (reason: string) => void

Why is this addon not supported?

unsupported
, isKit: anyisKit }) => {
if (!isKit: anyisKit) unsupported: (reason: string) => void

Why is this addon not supported?

unsupported
('Requires SvelteKit');
dependsOn: (name: keyof OfficialAddons) => void

On what official addons does this addon depend on?

dependsOn
('eslint');
}, // the actual work — add files, edit files, declare dependencies
run: (workspace: Workspace & {
    options: OptionValues<{}>;
    sv: SvApi;
    cancel: (reason: string) => void;
}) => MaybePromise<void>

Run the addon. The actual execution of the addon... Add files, edit files, etc.

run
: ({ sv: SvApi

Api to interact with the workspace.

sv
, options: OptionValues<{}>

Add-on options

options
, cancel: (reason: string) => void

Cancel the addon at any time!

cancel
}) => {
// add a dependency sv: SvApi

Api to interact with the workspace.

sv
.devDependency: (pkg: string, version: string) => void

Add a package to the dev dependencies.

devDependency
('my-lib', '^1.0.0');
// create or edit files using transforms from @sveltejs/sv-utils sv: SvApi

Api to interact with the workspace.

sv
.file: (path: string, edit: (content: string) => string) => void

Edit a file in the workspace. (will create it if it doesn't exist)

file
('src/lib/foo.ts', (content: stringcontent) => {
return 'export const foo = true;'; }); sv: SvApi

Api to interact with the workspace.

sv
.file: (path: string, edit: (content: string) => string) => void

Edit a file in the workspace. (will create it if it doesn't exist)

file
(
'src/routes/+page.svelte', import transformstransforms.svelte(({ ast: anyast, svelte: anysvelte }) => { svelte: anysvelte.addFragment(ast: anyast, '<p>Hello!</p>'); }) ); // cancel at any point if something is wrong // cancel('reason'); }, // displayed after the add-on runs
nextSteps?: ((data: Workspace & {
    options: OptionValues<{}>;
}) => string[]) | undefined

Next steps to display after the addon is run.

nextSteps
: ({ options: OptionValues<{}>options }) => ['Run `npm run dev` to get started']
});

The sv object in run provides file, dependency, devDependency, execute, and pnpmBuildDependency. For file transforms (AST-based editing of scripts, Svelte components, CSS, JSON, etc.), see @sveltejs/sv-utils.

defineAddonOptions

Builder for add-on options. Chained with .add() and finalized with .build().

import { function defineAddonOptions(): OptionBuilder<{}>

Options for an addon.

Will be prompted to the user if there are not answered by args when calling the cli.

const options = defineAddonOptions()
  .add('demo', {
	question: `demo? ${color.optional('(a cool one!)')}`
	type: string | boolean | number | select | multiselect,
	default: true,
  })
  .build();

To define by args, you can do

npx sv add <addon>=<option1>:<value1>+<option2>:<value2>
defineAddonOptions
} from 'sv';
const
const options: {
    database: {
        readonly question: "Which database?";
        readonly type: "select";
        readonly default: "postgresql";
        readonly options: [{
            readonly value: "postgresql";
        }, {
            readonly value: "mysql";
        }, {
            readonly value: "sqlite";
        }];
    };
    docker: {
        readonly question: "Add a docker-compose file?";
        readonly type: "boolean";
        readonly default: false;
        readonly condition: (opts: OptionValues<Record<"database", {
            readonly question: "Which database?";
            readonly type: "select";
            readonly default: "postgresql";
            readonly options: [{
                readonly value: "postgresql";
            }, {
                readonly value: "mysql";
            }, {
                readonly value: "sqlite";
            }];
        }> & Record<...>>) => boolean;
    };
}
options
= function defineAddonOptions(): OptionBuilder<{}>

Options for an addon.

Will be prompted to the user if there are not answered by args when calling the cli.

const options = defineAddonOptions()
  .add('demo', {
	question: `demo? ${color.optional('(a cool one!)')}`
	type: string | boolean | number | select | multiselect,
	default: true,
  })
  .build();

To define by args, you can do

npx sv add <addon>=<option1>:<value1>+<option2>:<value2>
defineAddonOptions
()
.
add<"database", {
    readonly question: "Which database?";
    readonly type: "select";
    readonly default: "postgresql";
    readonly options: [{
        readonly value: "postgresql";
    }, {
        readonly value: "mysql";
    }, {
        readonly value: "sqlite";
    }];
}>(key: "database", question: {
    readonly question: "Which database?";
    readonly type: "select";
    readonly default: "postgresql";
    readonly options: [{
        readonly value: "postgresql";
    }, {
        readonly value: "mysql";
    }, {
        readonly value: "sqlite";
    }];
}): OptionBuilder<Record<"database", {
    readonly question: "Which database?";
    readonly type: "select";
    readonly default: "postgresql";
    readonly options: [{
        readonly value: "postgresql";
    }, {
        readonly value: "mysql";
    }, {
        readonly value: "sqlite";
    }];
}>>

This type is a bit complex, but in usage, it's quite simple!

The idea is to add() options one by one, with the key and the question.

  .add('demo', {
	question: 'Do you want to add a demo?',
	type: 'boolean',  // string, number, select, multiselect
	default: true,
	// condition: (o) => o.previousOption === 'ok',
  })
add
('database', {
question: "Which database?"question: 'Which database?', type: "select"type: 'select', default: "postgresql"default: 'postgresql',
options: [{
    readonly value: "postgresql";
}, {
    readonly value: "mysql";
}, {
    readonly value: "sqlite";
}]
options
: [
{ value: "postgresql"value: 'postgresql' }, { value: "mysql"value: 'mysql' }, { value: "sqlite"value: 'sqlite' } ] }) .
add<"docker", {
    readonly question: "Add a docker-compose file?";
    readonly type: "boolean";
    readonly default: false;
    readonly condition: (opts: OptionValues<Record<"database", {
        readonly question: "Which database?";
        readonly type: "select";
        readonly default: "postgresql";
        readonly options: [{
            readonly value: "postgresql";
        }, {
            readonly value: "mysql";
        }, {
            readonly value: "sqlite";
        }];
    }> & Record<"docker", any>>) => boolean;
}>(key: "docker", question: {
    readonly question: "Add a docker-compose file?";
    readonly type: "boolean";
    readonly default: false;
    readonly condition: (opts: OptionValues<Record<"database", {
        readonly question: "Which database?";
        readonly type: "select";
        readonly default: "postgresql";
        readonly options: [{
            readonly value: "postgresql";
        }, {
            readonly value: "mysql";
        }, {
            readonly value: "sqlite";
        }];
    }> & Record<"docker", any>>) => boolean;
}): OptionBuilder<...>

This type is a bit complex, but in usage, it's quite simple!

The idea is to add() options one by one, with the key and the question.

  .add('demo', {
	question: 'Do you want to add a demo?',
	type: 'boolean',  // string, number, select, multiselect
	default: true,
	// condition: (o) => o.previousOption === 'ok',
  })
add
('docker', {
question: "Add a docker-compose file?"question: 'Add a docker-compose file?', type: "boolean"type: 'boolean', default: falsedefault: false, // only ask when database is not sqlite
condition: (opts: OptionValues<Record<"database", {
    readonly question: "Which database?";
    readonly type: "select";
    readonly default: "postgresql";
    readonly options: [{
        readonly value: "postgresql";
    }, {
        readonly value: "mysql";
    }, {
        readonly value: "sqlite";
    }];
}> & Record<"docker", any>>) => boolean
condition
: (
opts: OptionValues<Record<"database", {
    readonly question: "Which database?";
    readonly type: "select";
    readonly default: "postgresql";
    readonly options: [{
        readonly value: "postgresql";
    }, {
        readonly value: "mysql";
    }, {
        readonly value: "sqlite";
    }];
}> & Record<"docker", any>>
opts
) =>
opts: OptionValues<Record<"database", {
    readonly question: "Which database?";
    readonly type: "select";
    readonly default: "postgresql";
    readonly options: [{
        readonly value: "postgresql";
    }, {
        readonly value: "mysql";
    }, {
        readonly value: "sqlite";
    }];
}> & Record<"docker", any>>
opts
.database: "postgresql" | "mysql" | "sqlite"database !== 'sqlite'
}) .
function build(): {
    database: {
        readonly question: "Which database?";
        readonly type: "select";
        readonly default: "postgresql";
        readonly options: [{
            readonly value: "postgresql";
        }, {
            readonly value: "mysql";
        }, {
            readonly value: "sqlite";
        }];
    };
    docker: {
        readonly question: "Add a docker-compose file?";
        readonly type: "boolean";
        readonly default: false;
        readonly condition: (opts: OptionValues<Record<"database", {
            readonly question: "Which database?";
            readonly type: "select";
            readonly default: "postgresql";
            readonly options: [{
                readonly value: "postgresql";
            }, {
                readonly value: "mysql";
            }, {
                readonly value: "sqlite";
            }];
        }> & Record<...>>) => boolean;
    };
}

Finalize all options of your add-on.

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 { function create(cwd: string, options: Options): voidcreate } from 'sv';

function create(cwd: string, options: Options): voidcreate('./my-app', {
	name: stringname: 'my-app',
	template: "minimal" | "demo" | "library" | "addon" | "svelte"template: 'minimal',
	types: "typescript" | "checkjs" | "none"types: 'typescript'
});

add

Programmatically run add-ons against an existing project.

import { 
function add<Addons extends AddonMap>({ addons, cwd, options, packageManager }: InstallOptions<Addons>): Promise<ReturnType<({ loadedAddons, workspace, setupResults, options }: ApplyAddonOptions) => Promise<{
    filesToFormat: string[];
    pnpmBuildDependencies: string[];
    status: Record<string, string[] | "success">;
}>>>
add
, const officialAddons: OfficialAddonsofficialAddons } from 'sv';
await
add<{
    prettier: Addon<any, string>;
}>({ addons, cwd, options, packageManager }: InstallOptions<{
    prettier: Addon<any, string>;
}>): Promise<ReturnType<({ loadedAddons, workspace, setupResults, options }: ApplyAddonOptions) => Promise<{
    filesToFormat: string[];
    pnpmBuildDependencies: string[];
    status: Record<string, string[] | "success">;
}>>>
add
({
cwd: stringcwd: './my-app',
addons: {
    prettier: Addon<any, string>;
}
addons
: { prettier: Addon<any, string>prettier: const officialAddons: OfficialAddonsofficialAddons.prettier: Addon<any, string>prettier },
options: OptionMap<{
    prettier: Addon<any, string>;
}>
options
: { prettier: {}prettier: {} },
packageManager?: AgentName | undefinedpackageManager: 'npm' });

Edit this page on GitHub llms.txt