Skip to content

Commit c515007

Browse files
Sync cli docs (#1906)
sync cli docs Co-authored-by: svelte-docs-bot[bot] <196124396+svelte-docs-bot[bot]@users.noreply.github.com>
1 parent a1c5107 commit c515007

10 files changed

Lines changed: 423 additions & 268 deletions

File tree

apps/svelte.dev/content/docs/cli/20-commands/20-sv-add.md

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -72,49 +72,23 @@ Prevents installing dependencies
7272
> [!NOTE]
7373
> Svelte maintainers have not reviewed community add-ons for malicious code!
7474
75-
You can find [community add-ons on npm](https://www.npmx.dev/search?q=keyword:sv-add) by searching for keyword: `sv-add`.
76-
77-
### How to install a community add-on
78-
79-
```sh
80-
npx sv add [PROTOCOL][COMMUNITY_ADDON]
81-
```
82-
83-
You can:
84-
85-
- mix and match official and community add-ons
86-
- use the interactive prompt or give args to the cli
87-
- use the `--add` option in the `create` command
88-
89-
```sh
90-
npx sv add eslint "@supacool"
91-
```
75+
Community add-ons are npm packages published by the community. Look out for add-ons from your favourite libraries and tools. _(soon)_ Many developers are building `sv` add-ons to make their integrations a one-liner. You can find them on [npmx](https://www.npmx.dev/search?q=keyword:sv-add) by searching for the keyword: `sv-add`.
9276

9377
```sh
94-
npx sv create --add eslint "@supacool"
95-
```
96-
97-
### Package Protocols
98-
99-
```sh
100-
# Scoped package: @org (preferred), we will look for @org/sv
101-
npx sv add "@supacool"
102-
103-
# Regular npm package (with or without scope)
104-
npx sv add my-cool-addon
78+
# Install a community add-on by org name (it will look at @org/sv)
79+
npx sv add @supacool
10580

106-
# Local add-on
81+
# Use a local add-on (for development or internal use)
10782
npx sv add file:../path/to/my-addon
108-
```
109-
110-
### How to create a community add-on
11183

112-
To start on a good track, create your add-on with the `addon` template.
84+
# Mix and match official and community add-ons
85+
npx sv add eslint @supacool
11386

114-
```sh
115-
npx sv create --template addon [path]
87+
# Also works when creating a new project directly
88+
npx sv create --add eslint @supacool
11689
```
11790

118-
In your new add-on directory, check out the `README.md` and `CONTRIBUTING.md` to get started.
91+
> [!NOTE]
92+
> On Windows PowerShell, `@` is a special character that should be escaped with single quotes. For example: `npx sv add '@supacool'`.
11993
120-
Then you can continue with the [API docs](/docs/cli/add-on) to start building your add-on. You can also have a look at the [official addons source code](https://github.com/sveltejs/cli/tree/main/packages/sv/src/addons) to get some inspiration on what can be done.
94+
Want to create your own? Check the [Add-on Docs](community).

apps/svelte.dev/content/docs/cli/30-add-ons/16-better-auth.md renamed to apps/svelte.dev/content/docs/cli/30-add-ons/02-better-auth.md

File renamed without changes.

apps/svelte.dev/content/docs/cli/30-add-ons/10-eslint.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ npx sv add eslint
1515

1616
- the relevant packages installed including `eslint-plugin-svelte`
1717
- an `eslint.config.js` file
18-
- updated `.vscode/settings.json`
18+
- updated `.vscode/extensions.json`
1919
- configured to work with TypeScript and `prettier` if you're using those packages
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
---
2+
NOTE: do not edit this file, it is generated in apps/svelte.dev/scripts/sync-docs/index.ts
3+
title: [create your own]
4+
---
5+
6+
> [!NOTE]
7+
> Community add-ons are currently **experimental**. The API may change. Don't use them in production yet!
8+
9+
This guide covers how to create, test, and publish community add-ons for `sv`.
10+
11+
## Quick start
12+
13+
The easiest way to create an add-on is by using the `addon` template:
14+
15+
```sh
16+
npx sv create --template addon [path]
17+
```
18+
19+
The newly created project will have a `README.md` and `CONTRIBUTING.md` to guide you along.
20+
21+
## Project structure
22+
23+
Typically, an add-on looks like this:
24+
25+
```js
26+
import { transforms } from '@sveltejs/sv-utils';
27+
import { defineAddon, defineAddonOptions } from 'sv';
28+
29+
export default defineAddon({
30+
id: 'addon-name',
31+
32+
shortDescription: 'a better description of what your addon does ;)',
33+
34+
options: defineAddonOptions()
35+
.add('who', {
36+
question: 'To whom should the addon say hello?',
37+
type: 'string' // boolean | number | select | multiselect
38+
})
39+
.build(),
40+
41+
setup: ({ dependsOn, isKit, unsupported }) => {
42+
if (!isKit) unsupported('Requires SvelteKit');
43+
dependsOn('vitest');
44+
},
45+
46+
run: ({ isKit, cancel, sv, options, file, language, directory }) => {
47+
// Add "Hello [who]!" to the root page
48+
sv.file(
49+
directory.kitRoutes + '/+page.svelte',
50+
transforms.svelte(({ ast, svelte }) => {
51+
svelte.addFragment(ast, `<p>Hello ${options.who}!</p>`);
52+
})
53+
);
54+
},
55+
56+
nextSteps: ({ options }) => ['enjoy the add-on!']
57+
});
58+
```
59+
60+
The Svelte CLI is split into two packages with a clear boundary:
61+
62+
- [**`sv`**](sv) = **where and when** to do it. It owns paths, workspace detection, dependency tracking, and file I/O. The engine orchestrates add-on execution.
63+
- [**`@sveltejs/sv-utils`**](sv-utils) = **what** to do to content. It provides parsers, language tooling, and typed transforms. Everything here is pure - no file system, no workspace awareness.
64+
65+
This separation means transforms are testable without a workspace and composable across add-ons.
66+
67+
## Development
68+
69+
You can run your add-on locally using the `file:` protocol:
70+
71+
```sh
72+
cd /path/to/test-project
73+
npx sv add file:../path/to/my-addon
74+
```
75+
76+
This allows you to iterate quickly without publishing to npm.
77+
78+
The `file:` protocol also works for custom or private add-ons that you don't intend to publish - for example, to standardize project setup across your team or organization.
79+
80+
> [!NOTE]
81+
> The `demo-add` script automatically builds your add-on before running it.
82+
83+
## Testing
84+
85+
The `sv/testing` module provides utilities for testing your add-on. `createSetupTest` is a factory that takes your vitest imports and returns a `setupTest` function. It creates real SvelteKit projects from templates, runs your add-on, and gives you access to the resulting files.
86+
87+
```js
88+
import { expect } from '@playwright/test';
89+
import fs from 'node:fs';
90+
import path from 'node:path';
91+
import { createSetupTest } from 'sv/testing';
92+
import * as vitest from 'vitest';
93+
import addon from './index.js';
94+
95+
const { test, testCases } = createSetupTest(vitest)(
96+
{ addon },
97+
{
98+
kinds: [
99+
{
100+
type: 'default',
101+
options: {
102+
'your-addon-name': { who: 'World' }
103+
}
104+
}
105+
],
106+
filter: (testCase) => testCase.variant.includes('kit'),
107+
browser: false
108+
}
109+
);
110+
111+
test.concurrent.for(testCases)('my-addon $kind.type $variant', async (testCase, ctx) => {
112+
const cwd = ctx.cwd(testCase);
113+
114+
const page = fs.readFileSync(path.resolve(cwd, 'src/routes/+page.svelte'), 'utf8');
115+
expect(page).toContain('Hello World!');
116+
});
117+
```
118+
119+
Your `vitest.config.js` must include the global setup from `sv/testing`:
120+
121+
```js
122+
import { defineConfig } from 'vitest/config';
123+
124+
export default defineConfig({
125+
test: {
126+
include: ['tests/**/*.test.{js,ts}'],
127+
globalSetup: ['tests/setup/global.js']
128+
}
129+
});
130+
```
131+
132+
And the global test setup script `tests/setup/global.js`:
133+
134+
```js
135+
import { fileURLToPath } from 'node:url';
136+
import { setupGlobal } from 'sv/testing';
137+
138+
const TEST_DIR = fileURLToPath(new URL('../../.test-output/', import.meta.url));
139+
140+
export default setupGlobal({ TEST_DIR });
141+
```
142+
143+
## Publishing
144+
145+
### Bundling
146+
147+
Community add-ons are bundled with [tsdown](https://tsdown.dev/) into a single file. Everything is bundled except `sv`. (It is a peer dependency provided at runtime.)
148+
149+
### `package.json`
150+
151+
Your add-on must have `sv` as a peer dependency and **no** `dependencies` in `package.json`:
152+
153+
```jsonc
154+
{
155+
"name": "@my-org/sv",
156+
"version": "1.0.0",
157+
"type": "module",
158+
// bundled entrypoint (tsdown outputs .mjs for ESM)
159+
"exports": {
160+
".": { "default": "./dist/index.mjs" }
161+
},
162+
"publishConfig": {
163+
"access": "public"
164+
},
165+
// cannot have dependencies
166+
"dependencies": {},
167+
"peerDependencies": {
168+
// minimum version required to run by this add-on
169+
"sv": "^0.13.0"
170+
},
171+
// Add the "sv-add" keyword so users can discover your add-on
172+
"keywords": ["sv-add", "svelte", "sveltekit"]
173+
}
174+
```
175+
176+
### Naming convention
177+
178+
#### packages names
179+
180+
If you name your package `@my-org/sv`, users can install it by typing just the org handle:
181+
182+
```sh
183+
npx sv add @my-org
184+
```
185+
186+
It's also possible to publish like `@my-org/core`, just users will need to type the full package name.
187+
188+
```sh
189+
npx sv add @my-org/core
190+
```
191+
192+
Users can also ask for a specific version:
193+
194+
```sh
195+
npx sv add @my-org/sv@1.2.3
196+
```
197+
198+
When no version is specified, `latest` is used.
199+
200+
> [!NOTE]
201+
> Unscoped packages are not supported yet
202+
203+
#### export options
204+
205+
`sv` first tries to import `your-package/sv`, then falls back to the default export. This means you have two options:
206+
207+
1. **Default export** (for dedicated add-on packages):
208+
209+
```json
210+
{
211+
"exports": {
212+
".": "./src/index.js"
213+
}
214+
}
215+
```
216+
217+
2. **`./sv` export** (for packages that also export other functionality):
218+
```json
219+
{
220+
"exports": {
221+
".": "./src/main.js",
222+
"./sv": "./src/addon.js"
223+
}
224+
}
225+
```
226+
227+
### Publish to npm
228+
229+
```sh
230+
npm login
231+
npm publish
232+
```
233+
234+
> `prepublishOnly` automatically runs the build before publishing.
235+
236+
## Next steps
237+
238+
You can optionally display guidance in the console after your add-on runs:
239+
240+
```js
241+
import { color } from '@sveltejs/sv-utils';
242+
243+
export default defineAddon({
244+
// ...
245+
246+
nextSteps: ({ options }) => [
247+
`Run ${color.command('npm run dev')} to start developing`,
248+
`Check out the docs at https://...`
249+
]
250+
});
251+
```
252+
253+
## Version compatibility
254+
255+
Your add-on should specify a minimum `sv` version in `peerDependencies`. Your users will get a compatibility warning if their `sv` version has a different major version than what was specified.
256+
257+
## Examples
258+
259+
See the [official add-on source code](https://github.com/sveltejs/cli/tree/main/packages/sv/src/addons) for some real world examples.

0 commit comments

Comments
 (0)