Skip to main content

sv-utils

@sveltejs/sv-utils is currently experimental. The API may change.

@sveltejs/sv-utils is an add-on utility for parsing, transforming, and generating code..

npm install -D @sveltejs/sv-utils

transforms

transforms is a collection of parser-aware functions that lets you modify the files via abstract syntax tree (AST). It accepts a callback function. The return value is designed to be be passed directly into sv.file(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as Svelte because you never call a parser yourself.

Each transform injects relevant utilities into the callback, so you only need one import:

import { 
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
} from '@sveltejs/sv-utils';
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
.
function script(cb: (file: {
    ast: Program;
    comments: Comments;
    content: string;
    js: typeof index_d_exports$3;
}) => void | false, options?: TransformOptions): (content: string) => string

Transform a JavaScript/TypeScript file.

Return false from the callback to abort - the original content is returned unchanged.

script
(/* ... */);
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
.
function svelte(cb: (file: {
    ast: AST.Root;
    content: string;
    svelte: typeof index_d_exports$4;
    js: typeof index_d_exports$3;
}) => void | false, options?: TransformOptions): (content: string) => string

Transform a Svelte component file.

Return false from the callback to abort - the original content is returned unchanged.

svelte
(/* ... */);
// ...

transforms.script

Transform a JavaScript/TypeScript file. The callback receives { ast, comments, content, js }.

import { 
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
} from '@sveltejs/sv-utils';
sv.file( file.viteConfig,
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
.
function script(cb: (file: {
    ast: Program;
    comments: Comments;
    content: string;
    js: typeof index_d_exports$3;
}) => void | false, options?: TransformOptions): (content: string) => string

Transform a JavaScript/TypeScript file.

Return false from the callback to abort - the original content is returned unchanged.

script
(({ ast: Programast, js: typeof index_d_exports$3js }) => {
js: typeof index_d_exports$3js.
namespace index_d_exports$3.imports
export index_d_exports$3.imports
imports
.
imports_d_exports.addDefault(node: Program, options: {
    from: string;
    as: string;
}): void
export imports_d_exports.addDefault
addDefault
(ast: Programast, { as: stringas: 'foo', from: stringfrom: 'foo' });
js: typeof index_d_exports$3js.
namespace index_d_exports$3.vite
export index_d_exports$3.vite
vite
.
vite_d_exports.addPlugin(ast: Program, options: {
    code: string;
    mode?: "append" | "prepend";
}): void
export vite_d_exports.addPlugin
addPlugin
(ast: Programast, { code: stringcode: 'foo()' });
}) );

transforms.svelte

Transform a Svelte component. The callback receives { ast, content, svelte, js }.

import { 
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
} from '@sveltejs/sv-utils';
sv.file( layoutPath,
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
.
function svelte(cb: (file: {
    ast: AST.Root;
    content: string;
    svelte: typeof index_d_exports$4;
    js: typeof index_d_exports$3;
}) => void | false, options?: TransformOptions): (content: string) => string

Transform a Svelte component file.

Return false from the callback to abort - the original content is returned unchanged.

svelte
(({ ast: AST.Rootast, svelte: typeof index_d_exports$4svelte }) => {
svelte: typeof index_d_exports$4svelte.
index_d_exports$4.addFragment(ast: AST.Root, content: string, options?: {
    mode?: "append" | "prepend";
    language?: "ts" | "js";
}): void
export index_d_exports$4.addFragment
addFragment
(ast: AST.Rootast, '<Foo />');
}) );

transforms.svelteScript

Transform a Svelte component with a <script> block guaranteed. Pass { language } as the first argument. The callback receives { ast, content, svelte, js } where ast.instance is always non-null.

import { 
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
} from '@sveltejs/sv-utils';
sv.file( layoutPath,
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
.
function svelteScript(scriptOptions: {
    language: "ts" | "js";
}, cb: (file: {
    ast: RootWithInstance;
    content: string;
    svelte: typeof index_d_exports$4;
    js: typeof index_d_exports$3;
}) => void | false, options?: TransformOptions): TransformFn

Transform a Svelte component file with a script block guaranteed.

Calls ensureScript before invoking your callback, so ast.instance is always non-null. Pass { language } as the first argument to set the script language.

Return false from the callback to abort - the original content is returned unchanged.

svelteScript
({ language: "ts" | "js"language: 'ts' }, ({ ast: RootWithInstanceast, svelte: typeof index_d_exports$4svelte, js: typeof index_d_exports$3js }) => {
js: typeof index_d_exports$3js.
namespace index_d_exports$3.imports
export index_d_exports$3.imports
imports
.
imports_d_exports.addDefault(node: Program, options: {
    from: string;
    as: string;
}): void
export imports_d_exports.addDefault
addDefault
(ast: RootWithInstanceast.instance: AST.Script

The parsed <script> element, if exists

instance
.AST.Script.content: Programcontent, { as: stringas: 'Foo', from: stringfrom: './Foo.svelte' });
svelte: typeof index_d_exports$4svelte.
index_d_exports$4.addFragment(ast: AST.Root, content: string, options?: {
    mode?: "append" | "prepend";
    language?: "ts" | "js";
}): void
export index_d_exports$4.addFragment
addFragment
(ast: RootWithInstanceast, '<Foo />');
}) );

transforms.css

Transform a CSS file. The callback receives { ast, content, css }.

import { 
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
} from '@sveltejs/sv-utils';
sv.file( file.stylesheet,
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
.
function css(cb: (file: {
    ast: Omit<_CSS.StyleSheetBase, "attributes" | "content">;
    content: string;
    css: typeof index_d_exports$1;
}) => void | false, options?: TransformOptions): TransformFn

Transform a CSS file.

Return false from the callback to abort - the original content is returned unchanged.

css
(({ ast: Omit<_CSS.StyleSheetBase, "attributes" | "content">ast, css: typeof index_d_exports$1css }) => {
css: typeof index_d_exports$1css.
index_d_exports$1.addAtRule(node: _CSS.StyleSheetBase, options: {
    name: string;
    params: string;
    append: boolean;
}): _CSS.Atrule
export index_d_exports$1.addAtRule
addAtRule
(ast: Omit<_CSS.StyleSheetBase, "attributes" | "content">ast, { name: stringname: 'import', params: stringparams: "'tailwindcss'" });
}) );

transforms.json

Transform a JSON file. Mutate the data object directly. The callback receives { data, content, json }.

import { 
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
} from '@sveltejs/sv-utils';
sv.file( file.typeConfig,
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
.
json<any>(cb: (file: {
    data: any;
    content: string;
    json: typeof json_d_exports;
}) => void | false, options?: TransformOptions): TransformFn

Transform a JSON file.

Return false from the callback to abort - the original content is returned unchanged.

json
(({ data: anydata }) => {
data: anydata.compilerOptions ??= {}; data: anydata.compilerOptions.strict = true; }) );

transforms.yaml / transforms.toml

Same pattern as transforms.json, for YAML and TOML files respectively. The callback receives { data, content }.

transforms.text

Transform a plain text file (.env, .gitignore, etc.). No parser - string in, string out. The callback receives { content, text }.

import { 
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
} from '@sveltejs/sv-utils';
sv.file( '.env',
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
.
function text(cb: (file: {
    content: string;
    text: typeof text_d_exports;
}) => string | false): TransformFn

Transform a plain text file (.env, .gitignore, etc.).

Unlike other transforms there's no AST here - just string in, string out. Return the new content, or false to abort (original content is returned unchanged).

text
(({ content: stringcontent }) => {
return content: stringcontent + '\nDATABASE_URL="file:local.db"'; }) );

Aborting a transform

Return false from any transform callback to abort - the original content is returned unchanged.

import { 
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
} from '@sveltejs/sv-utils';
sv.file( 'eslint.config.js',
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
.
function script(cb: (file: {
    ast: Program;
    comments: Comments;
    content: string;
    js: typeof index_d_exports$3;
}) => void | false, options?: TransformOptions): (content: string) => string

Transform a JavaScript/TypeScript file.

Return false from the callback to abort - the original content is returned unchanged.

script
(({ ast: Programast, js: typeof index_d_exports$3js }) => {
const { value: anyvalue: const existing: anyexisting } = js: typeof index_d_exports$3js.
namespace index_d_exports$3.exports
export index_d_exports$3.exports
exports
.
exports_d_exports.createDefault<any>(node: Program, options: {
    fallback: any;
}): ExportDefaultResult<any>
export exports_d_exports.createDefault
createDefault
(ast: Programast, { fallback: anyfallback: myConfig });
if (const existing: anyexisting !== myConfig) { // config already exists, don't touch it return false; } // ... continue modifying ast }) );

Standalone usage & testing

Transforms are curried functions - call them with the callback, then apply to content:

import { 
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
} from '@sveltejs/sv-utils';
const const transform: (content: string) => stringtransform =
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
.
function script(cb: (file: {
    ast: Program;
    comments: Comments;
    content: string;
    js: typeof index_d_exports$3;
}) => void | false, options?: TransformOptions): (content: string) => string

Transform a JavaScript/TypeScript file.

Return false from the callback to abort - the original content is returned unchanged.

script
(({ ast: Programast, js: typeof index_d_exports$3js }) => {
js: typeof index_d_exports$3js.
namespace index_d_exports$3.imports
export index_d_exports$3.imports
imports
.
imports_d_exports.addDefault(node: Program, options: {
    from: string;
    as: string;
}): void
export imports_d_exports.addDefault
addDefault
(ast: Programast, { as: stringas: 'foo', from: stringfrom: 'foo' });
}); const const result: stringresult = const transform: (content: string) => stringtransform('export default {}');

Composability

For cases where you need to mix and match transforms and raw edits, use sv.file with a content callback and invoke the curried transform manually:

sv.file(path, (content: anycontent) => {
	// curried
	const const transform: anytransform = transforms.script(({ ast: anyast, js: anyjs }) => {
		js: anyjs.imports.addDefault(ast: anyast, { as: stringas: 'foo', from: stringfrom: 'bar' });
	});

	// parser manipulation
	content: anycontent = const transform: anytransform(content: anycontent);

	// raw string manipulation
	content: anycontent = content: anycontent.replace('foo', 'baz');

	return content: anycontent;
});

Add-ons can also export reusable transform functions:

import { 
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
} from '@sveltejs/sv-utils';
// reusable - export from your package export const const addFooImport: (content: string) => stringaddFooImport =
const transforms: {
    script(cb: (file: {
        ast: Program;
        comments: Comments;
        content: string;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    svelte(cb: (file: {
        ast: AST.Root;
        content: string;
        svelte: typeof index_d_exports$4;
        js: typeof index_d_exports$3;
    }) => void | false, options?: TransformOptions): (content: string) => string;
    ... 6 more ...;
    text(cb: (file: {
        content: string;
        text: typeof text_d_exports;
    }) => string | false): TransformFn;
}

File transform primitives that know their format.

sv-utils = what to do to content, sv = where and when to do it.

Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode(). The parser choice is baked into the transform type - you can't accidentally parse a vite config as svelte because you never call a parser yourself.

Transforms are curried: call with the callback to get a (content: string) => string function that plugs directly into sv.file().

@example
import { transforms } from '@sveltejs/sv-utils';

// use with sv.file() - curried form plugs in directly
sv.file(files.viteConfig, transforms.script(({ ast, js }) => {
  js.vite.addPlugin(ast, { code: 'kitRoutes()' });
}));

// standalone usage / testing
const result = transforms.script(({ ast, js }) => {
  js.imports.addDefault(ast, { as: 'foo', from: 'foo' });
})(fileContent);
transforms
.
function svelte(cb: (file: {
    ast: AST.Root;
    content: string;
    svelte: typeof index_d_exports$4;
    js: typeof index_d_exports$3;
}) => void | false, options?: TransformOptions): (content: string) => string

Transform a Svelte component file.

Return false from the callback to abort - the original content is returned unchanged.

svelte
(({ ast: AST.Rootast, svelte: typeof index_d_exports$4svelte, js: typeof index_d_exports$3js }) => {
svelte: typeof index_d_exports$4svelte.
index_d_exports$4.ensureScript(ast: AST.Root, options?: {
    language?: "ts" | "js";
}): asserts ast is RootWithInstance
export index_d_exports$4.ensureScript
ensureScript
(ast: AST.Rootast, { language?: "js" | "ts" | undefinedlanguage });
js: typeof index_d_exports$3js.
namespace index_d_exports$3.imports
export index_d_exports$3.imports
imports
.
imports_d_exports.addDefault(node: Program, options: {
    from: string;
    as: string;
}): void
export imports_d_exports.addDefault
addDefault
(ast: AST.Rootast.AST.Root.instance: AST.Script | null

The parsed <script> element, if exists

instance
.AST.Script.content: Programcontent, { as: stringas: 'Foo', from: stringfrom: './Foo.svelte' });
});
sv.file('+page.svelte', addFooImport);
sv.file('index.svelte', addFooImport);

Parsers (low-level)

transforms will fit most users needs (e.g., conditional parsing, error handling around the parser). If not, parse is a low-level API available to you:

import { 
const parse: {
    css: (source: string) => {
        ast: Omit<_CSS.StyleSheetBase, "attributes" | "content">;
    } & ParseBase;
    html: (source: string) => {
        ast: AST.Fragment;
    } & ParseBase;
    json: (source: string) => {
        data: any;
    } & ParseBase;
    script: (source: string) => {
        ast: Program;
        comments: Comments;
    } & ParseBase;
    svelte: (source: string) => {
        ast: AST.Root;
    } & ParseBase;
    toml: (source: string) => {
        data: TomlTable;
    } & ParseBase;
    yaml: (source: string) => {
        data: YamlDocument;
    } & ParseBase;
}

Low-level parsers. Prefer transforms for add-on file edits — it picks the right parser for you and handles generateCode() automatically.

Use parse directly when you need error handling around parsing or conditional parser selection at runtime.

import { parse } from '@sveltejs/sv-utils';

const { ast, generateCode } = parse.script('function add(a, b) { return a + b; }');
const { ast, generateCode } = parse.svelte('<div>Hello, world!</div>');
const { ast, generateCode } = parse.css('body { color: red; }');
const { data, generateCode } = parse.json('{ "name": "John", "age": 30 }');
const { data, generateCode } = parse.yaml('name: John');
const { data, generateCode } = parse.toml('name = "John"');
const { ast, generateCode } = parse.html('<div>Hello, world!</div>');
parse
} from '@sveltejs/sv-utils';
const { const ast: Programast, const generateCode: () => string

Generate the code after manipulating the ast.

import { svelte } from 'sv/core';
const { ast, generateCode } = parse.svelte(content);

svelte.addFragment(ast, '<p>Hello World</p>');

const code = generateCode();
generateCode
} =
const parse: {
    css: (source: string) => {
        ast: Omit<_CSS.StyleSheetBase, "attributes" | "content">;
    } & ParseBase;
    html: (source: string) => {
        ast: AST.Fragment;
    } & ParseBase;
    json: (source: string) => {
        data: any;
    } & ParseBase;
    script: (source: string) => {
        ast: Program;
        comments: Comments;
    } & ParseBase;
    svelte: (source: string) => {
        ast: AST.Root;
    } & ParseBase;
    toml: (source: string) => {
        data: TomlTable;
    } & ParseBase;
    yaml: (source: string) => {
        data: YamlDocument;
    } & ParseBase;
}

Low-level parsers. Prefer transforms for add-on file edits — it picks the right parser for you and handles generateCode() automatically.

Use parse directly when you need error handling around parsing or conditional parser selection at runtime.

import { parse } from '@sveltejs/sv-utils';

const { ast, generateCode } = parse.script('function add(a, b) { return a + b; }');
const { ast, generateCode } = parse.svelte('<div>Hello, world!</div>');
const { ast, generateCode } = parse.css('body { color: red; }');
const { data, generateCode } = parse.json('{ "name": "John", "age": 30 }');
const { data, generateCode } = parse.yaml('name: John');
const { data, generateCode } = parse.toml('name = "John"');
const { ast, generateCode } = parse.html('<div>Hello, world!</div>');
parse
.
script: (source: string) => {
    ast: Program;
    comments: Comments;
} & ParseBase
script
(content);
const { const ast: AST.Rootast, const generateCode: () => string

Generate the code after manipulating the ast.

import { svelte } from 'sv/core';
const { ast, generateCode } = parse.svelte(content);

svelte.addFragment(ast, '<p>Hello World</p>');

const code = generateCode();
generateCode
} =
const parse: {
    css: (source: string) => {
        ast: Omit<_CSS.StyleSheetBase, "attributes" | "content">;
    } & ParseBase;
    html: (source: string) => {
        ast: AST.Fragment;
    } & ParseBase;
    json: (source: string) => {
        data: any;
    } & ParseBase;
    script: (source: string) => {
        ast: Program;
        comments: Comments;
    } & ParseBase;
    svelte: (source: string) => {
        ast: AST.Root;
    } & ParseBase;
    toml: (source: string) => {
        data: TomlTable;
    } & ParseBase;
    yaml: (source: string) => {
        data: YamlDocument;
    } & ParseBase;
}

Low-level parsers. Prefer transforms for add-on file edits — it picks the right parser for you and handles generateCode() automatically.

Use parse directly when you need error handling around parsing or conditional parser selection at runtime.

import { parse } from '@sveltejs/sv-utils';

const { ast, generateCode } = parse.script('function add(a, b) { return a + b; }');
const { ast, generateCode } = parse.svelte('<div>Hello, world!</div>');
const { ast, generateCode } = parse.css('body { color: red; }');
const { data, generateCode } = parse.json('{ "name": "John", "age": 30 }');
const { data, generateCode } = parse.yaml('name: John');
const { data, generateCode } = parse.toml('name = "John"');
const { ast, generateCode } = parse.html('<div>Hello, world!</div>');
parse
.
svelte: (source: string) => {
    ast: AST.Root;
} & ParseBase
svelte
(content);
const { const ast: Omit<_CSS.StyleSheetBase, "attributes" | "content">ast, const generateCode: () => string

Generate the code after manipulating the ast.

import { svelte } from 'sv/core';
const { ast, generateCode } = parse.svelte(content);

svelte.addFragment(ast, '<p>Hello World</p>');

const code = generateCode();
generateCode
} =
const parse: {
    css: (source: string) => {
        ast: Omit<_CSS.StyleSheetBase, "attributes" | "content">;
    } & ParseBase;
    html: (source: string) => {
        ast: AST.Fragment;
    } & ParseBase;
    json: (source: string) => {
        data: any;
    } & ParseBase;
    script: (source: string) => {
        ast: Program;
        comments: Comments;
    } & ParseBase;
    svelte: (source: string) => {
        ast: AST.Root;
    } & ParseBase;
    toml: (source: string) => {
        data: TomlTable;
    } & ParseBase;
    yaml: (source: string) => {
        data: YamlDocument;
    } & ParseBase;
}

Low-level parsers. Prefer transforms for add-on file edits — it picks the right parser for you and handles generateCode() automatically.

Use parse directly when you need error handling around parsing or conditional parser selection at runtime.

import { parse } from '@sveltejs/sv-utils';

const { ast, generateCode } = parse.script('function add(a, b) { return a + b; }');
const { ast, generateCode } = parse.svelte('<div>Hello, world!</div>');
const { ast, generateCode } = parse.css('body { color: red; }');
const { data, generateCode } = parse.json('{ "name": "John", "age": 30 }');
const { data, generateCode } = parse.yaml('name: John');
const { data, generateCode } = parse.toml('name = "John"');
const { ast, generateCode } = parse.html('<div>Hello, world!</div>');
parse
.
css: (source: string) => {
    ast: Omit<_CSS.StyleSheetBase, "attributes" | "content">;
} & ParseBase
css
(content);
const { const data: anydata, const generateCode: () => string

Generate the code after manipulating the ast.

import { svelte } from 'sv/core';
const { ast, generateCode } = parse.svelte(content);

svelte.addFragment(ast, '<p>Hello World</p>');

const code = generateCode();
generateCode
} =
const parse: {
    css: (source: string) => {
        ast: Omit<_CSS.StyleSheetBase, "attributes" | "content">;
    } & ParseBase;
    html: (source: string) => {
        ast: AST.Fragment;
    } & ParseBase;
    json: (source: string) => {
        data: any;
    } & ParseBase;
    script: (source: string) => {
        ast: Program;
        comments: Comments;
    } & ParseBase;
    svelte: (source: string) => {
        ast: AST.Root;
    } & ParseBase;
    toml: (source: string) => {
        data: TomlTable;
    } & ParseBase;
    yaml: (source: string) => {
        data: YamlDocument;
    } & ParseBase;
}

Low-level parsers. Prefer transforms for add-on file edits — it picks the right parser for you and handles generateCode() automatically.

Use parse directly when you need error handling around parsing or conditional parser selection at runtime.

import { parse } from '@sveltejs/sv-utils';

const { ast, generateCode } = parse.script('function add(a, b) { return a + b; }');
const { ast, generateCode } = parse.svelte('<div>Hello, world!</div>');
const { ast, generateCode } = parse.css('body { color: red; }');
const { data, generateCode } = parse.json('{ "name": "John", "age": 30 }');
const { data, generateCode } = parse.yaml('name: John');
const { data, generateCode } = parse.toml('name = "John"');
const { ast, generateCode } = parse.html('<div>Hello, world!</div>');
parse
.
json: (source: string) => {
    data: any;
} & ParseBase
json
(content);
const { const data: YamlDocumentdata, const generateCode: () => string

Generate the code after manipulating the ast.

import { svelte } from 'sv/core';
const { ast, generateCode } = parse.svelte(content);

svelte.addFragment(ast, '<p>Hello World</p>');

const code = generateCode();
generateCode
} =
const parse: {
    css: (source: string) => {
        ast: Omit<_CSS.StyleSheetBase, "attributes" | "content">;
    } & ParseBase;
    html: (source: string) => {
        ast: AST.Fragment;
    } & ParseBase;
    json: (source: string) => {
        data: any;
    } & ParseBase;
    script: (source: string) => {
        ast: Program;
        comments: Comments;
    } & ParseBase;
    svelte: (source: string) => {
        ast: AST.Root;
    } & ParseBase;
    toml: (source: string) => {
        data: TomlTable;
    } & ParseBase;
    yaml: (source: string) => {
        data: YamlDocument;
    } & ParseBase;
}

Low-level parsers. Prefer transforms for add-on file edits — it picks the right parser for you and handles generateCode() automatically.

Use parse directly when you need error handling around parsing or conditional parser selection at runtime.

import { parse } from '@sveltejs/sv-utils';

const { ast, generateCode } = parse.script('function add(a, b) { return a + b; }');
const { ast, generateCode } = parse.svelte('<div>Hello, world!</div>');
const { ast, generateCode } = parse.css('body { color: red; }');
const { data, generateCode } = parse.json('{ "name": "John", "age": 30 }');
const { data, generateCode } = parse.yaml('name: John');
const { data, generateCode } = parse.toml('name = "John"');
const { ast, generateCode } = parse.html('<div>Hello, world!</div>');
parse
.
yaml: (source: string) => {
    data: YamlDocument;
} & ParseBase
yaml
(content);
const { const data: TomlTabledata, const generateCode: () => string

Generate the code after manipulating the ast.

import { svelte } from 'sv/core';
const { ast, generateCode } = parse.svelte(content);

svelte.addFragment(ast, '<p>Hello World</p>');

const code = generateCode();
generateCode
} =
const parse: {
    css: (source: string) => {
        ast: Omit<_CSS.StyleSheetBase, "attributes" | "content">;
    } & ParseBase;
    html: (source: string) => {
        ast: AST.Fragment;
    } & ParseBase;
    json: (source: string) => {
        data: any;
    } & ParseBase;
    script: (source: string) => {
        ast: Program;
        comments: Comments;
    } & ParseBase;
    svelte: (source: string) => {
        ast: AST.Root;
    } & ParseBase;
    toml: (source: string) => {
        data: TomlTable;
    } & ParseBase;
    yaml: (source: string) => {
        data: YamlDocument;
    } & ParseBase;
}

Low-level parsers. Prefer transforms for add-on file edits — it picks the right parser for you and handles generateCode() automatically.

Use parse directly when you need error handling around parsing or conditional parser selection at runtime.

import { parse } from '@sveltejs/sv-utils';

const { ast, generateCode } = parse.script('function add(a, b) { return a + b; }');
const { ast, generateCode } = parse.svelte('<div>Hello, world!</div>');
const { ast, generateCode } = parse.css('body { color: red; }');
const { data, generateCode } = parse.json('{ "name": "John", "age": 30 }');
const { data, generateCode } = parse.yaml('name: John');
const { data, generateCode } = parse.toml('name = "John"');
const { ast, generateCode } = parse.html('<div>Hello, world!</div>');
parse
.
toml: (source: string) => {
    data: TomlTable;
} & ParseBase
toml
(content);
const { const ast: AST.Fragmentast, const generateCode: () => string

Generate the code after manipulating the ast.

import { svelte } from 'sv/core';
const { ast, generateCode } = parse.svelte(content);

svelte.addFragment(ast, '<p>Hello World</p>');

const code = generateCode();
generateCode
} =
const parse: {
    css: (source: string) => {
        ast: Omit<_CSS.StyleSheetBase, "attributes" | "content">;
    } & ParseBase;
    html: (source: string) => {
        ast: AST.Fragment;
    } & ParseBase;
    json: (source: string) => {
        data: any;
    } & ParseBase;
    script: (source: string) => {
        ast: Program;
        comments: Comments;
    } & ParseBase;
    svelte: (source: string) => {
        ast: AST.Root;
    } & ParseBase;
    toml: (source: string) => {
        data: TomlTable;
    } & ParseBase;
    yaml: (source: string) => {
        data: YamlDocument;
    } & ParseBase;
}

Low-level parsers. Prefer transforms for add-on file edits — it picks the right parser for you and handles generateCode() automatically.

Use parse directly when you need error handling around parsing or conditional parser selection at runtime.

import { parse } from '@sveltejs/sv-utils';

const { ast, generateCode } = parse.script('function add(a, b) { return a + b; }');
const { ast, generateCode } = parse.svelte('<div>Hello, world!</div>');
const { ast, generateCode } = parse.css('body { color: red; }');
const { data, generateCode } = parse.json('{ "name": "John", "age": 30 }');
const { data, generateCode } = parse.yaml('name: John');
const { data, generateCode } = parse.toml('name = "John"');
const { ast, generateCode } = parse.html('<div>Hello, world!</div>');
parse
.
html: (source: string) => {
    ast: AST.Fragment;
} & ParseBase
html
(content);

Language tooling

Namespaced helpers for AST manipulation:

  • js.* - imports, exports, objects, arrays, variables, functions, vite config helpers, SvelteKit helpers
  • css.* - rules, declarations, at-rules, imports
  • svelte.* - ensureScript, addSlot, addFragment
  • json.* - arrayUpsert, packageScriptsUpsert
  • html.* - attribute manipulation
  • text.* - upsert lines in flat files (.env, .gitignore)

Svelte config

The svelte/kit config can live in two places: passed straight to the sveltekit() plugin in vite.config.{js,ts}, or as a default export in a separate svelte.config.{js,ts}. Projects created by sv keep their config inside vite.config.js and ship no svelte.config.js.

svelteConfig lets add-ons read and edit that config wherever it lives - the sveltekit() argument in vite.config.{js,ts}, or a svelte.config.{js,ts} default export - without having to know which.

svelteConfig.edit

You address options by name and the helper writes each one to the right place, so you never deal with the kit nesting yourself. Svelte-level options (compilerOptions, preprocess, extensions, vitePlugin) sit on the config object; everything else (adapter, alias, files, typescript, …) is a kit option, which means flattened onto the sveltekit() argument in a vite config, or nested under kit in a svelte.config.

import { 
const svelteConfig: {
    edit: (target: {
        sv: SvFileApi;
        cwd: string;
    }, editFn: SvelteConfEdit) => void;
    find: (source: ConfigSource) => SvelteConfigLocation | null;
    read: (source: ConfigSource) => SvelteConfigObjects | null;
}

Helpers for the svelte/kit config, which can live either in a svelte.config.{js,ts} default export or in the object passed to sveltekit() in a vite.config.{js,ts}.

svelteConfig
} from '@sveltejs/sv-utils';
// inside an add-on's `run({ sv, cwd })`:
const svelteConfig: {
    edit: (target: {
        sv: SvFileApi;
        cwd: string;
    }, editFn: SvelteConfEdit) => void;
    find: (source: ConfigSource) => SvelteConfigLocation | null;
    read: (source: ConfigSource) => SvelteConfigObjects | null;
}

Helpers for the svelte/kit config, which can live either in a svelte.config.{js,ts} default export or in the object passed to sveltekit() in a vite.config.{js,ts}.

svelteConfig
.
edit: (target: {
    sv: SvFileApi;
    cwd: string;
}, editFn: SvelteConfEdit) => void

Edit the config wherever it lives (creating svelte.config.js if there is none).

edit
({ sv: SvFileApisv, cwd: stringcwd }, ({ ast: Programast,
property: <T extends Expression | Identifier>(name: string, opts: {
    fallback: T;
}) => T

Get-or-create a top-level config option's value, placed in the correct location for its name (kit-level options end up under kit in a svelte.config, flattened in a vite.config).

property
,
override: (props: ObjectMap$1, opts?: {
    dropLeadingComments?: string[];
}) => void

Set/override top-level config options, each routed to the correct location by its name. Pass dropLeadingComments with option names whose now-stale leading comments should be removed (e.g. the adapter-auto note when switching adapters).

override
, js: typeof index_d_exports$3js }) => {
// svelte-level option - get-or-create its value, then mutate in place: js: typeof index_d_exports$3js.
namespace index_d_exports$3.array
export index_d_exports$3.array
array
.
array_d_exports.append(node: ArrayExpression, element: string | Expression | SpreadElement): void
export array_d_exports.append
append
(
property: <ArrayExpression>(name: string, opts: {
    fallback: ArrayExpression;
}) => ArrayExpression

Get-or-create a top-level config option's value, placed in the correct location for its name (kit-level options end up under kit in a svelte.config, flattened in a vite.config).

property
('extensions', { fallback: ArrayExpressionfallback: js: typeof index_d_exports$3js.
namespace index_d_exports$3.array
export index_d_exports$3.array
array
.
array_d_exports.create(): ArrayExpression
export array_d_exports.create
create
() }), '.svx');
// kit option - routed automatically, no `kit` nesting to think about: js: typeof index_d_exports$3js.
namespace index_d_exports$3.imports
export index_d_exports$3.imports
imports
.
imports_d_exports.addDefault(node: Program, options: {
    from: string;
    as: string;
}): void
export imports_d_exports.addDefault
addDefault
(ast: Programast, { from: stringfrom: '@sveltejs/adapter-node', as: stringas: 'adapter' });
override: (props: ObjectMap$1, opts?: {
    dropLeadingComments?: string[];
}) => void

Set/override top-level config options, each routed to the correct location by its name. Pass dropLeadingComments with option names whose now-stale leading comments should be removed (e.g. the adapter-auto note when switching adapters).

override
({
adapter: CallExpressionadapter: js: typeof index_d_exports$3js.
namespace index_d_exports$3.functions
export index_d_exports$3.functions
functions
.
function_d_exports.createCall(options: {
    name: string;
    args: string[];
    useIdentifiers?: boolean;
}): CallExpression
export function_d_exports.createCall
createCall
({ name: stringname: 'adapter', args: string[]args: [], useIdentifiers?: boolean | undefineduseIdentifiers: true })
}); });
  • property(name, { fallback }) - get-or-create an option's value to mutate in place (arrays, nested objects).
  • override(props, { dropLeadingComments }) - set/replace options; dropLeadingComments clears a now-stale leading comment (e.g. the adapter-auto note when switching adapters).

It writes through sv.file, so the edit is tracked like any other. If the project has neither config file, a svelte.config.js is created.

svelteConfig.find / svelteConfig.read

Lower-level building blocks, both reading candidate files through an injected read(path) (returns the file contents or null) so detection stays static - the config is never executed:

  • svelteConfig.find(read) - returns { path, kind } or null (kind is 'vite' or 'svelte'; svelte.config wins when both are present).
  • svelteConfig.read(read) - locates and parses in one pass, returning { location, config, kit } (the object expressions) or null.

Package manager helpers

pnpm.allowBuilds

Returns a transform for pnpm-workspace.yaml that adds packages to the pnpm "allow builds" config. Use with sv.file when the project uses pnpm.

The helper detects the installed pnpm version via pnpm --version:

  • pnpm >= 11: writes to the unified allowBuilds map ({ pkg: true }), migrating any legacy onlyBuiltDependencies list into the map.
  • pnpm < 11: writes to the legacy onlyBuiltDependencies list.
import { pnpm } from '@sveltejs/sv-utils';

if (packageManager === 'pnpm') {
	sv.file(file.findUp('pnpm-workspace.yaml'), pnpm.
pnpm_d_exports.allowBuilds(...packages: string[]): TransformFn
export pnpm_d_exports.allowBuilds

Returns a TransformFn for pnpm-workspace.yaml that adds packages to the pnpm "allow builds" config.

The helper detects the installed pnpm version (via pnpm --version) and:

  • on pnpm >= 11 writes to the unified allowBuilds map ({ pkg: true }), migrating any legacy onlyBuiltDependencies list into the map;
  • on pnpm < 11 writes to the legacy onlyBuiltDependencies list.
if (packageManager === 'pnpm') {
  sv.file(file.findUp('pnpm-workspace.yaml'), pnpm.allowBuilds('my-native-dep'));
}
allowBuilds
('my-native-dep'));
}

Edit this page on GitHub llms.txt

previous next