Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
151 commits
Select commit Hold shift + click to select a range
bae54bb
Implementation of svelte.dev/packages only with no package search
benmccann Sep 5, 2025
4f9e1a5
remove unused code
benmccann Sep 19, 2025
22b615f
fix bad data
benmccann Sep 19, 2025
a9203db
add missing sv add-ons
benmccann Sep 19, 2025
23e3be0
add vite-plugin-devtools-json
benmccann Sep 19, 2025
1029b9a
add back alias
benmccann Sep 19, 2025
f4b7dfb
keep one packages-meta
jycouet Sep 20, 2025
ffa80fe
add sv cmd display
jycouet Sep 20, 2025
6082afe
add link to title of pkg
jycouet Sep 20, 2025
6df755f
rmv icon for border left
jycouet Sep 20, 2025
cd3b623
update main redirect (hompage or sv)
jycouet Sep 20, 2025
6590e5e
homelink & sv link
jycouet Sep 20, 2025
9f3052a
Merge branch 'main' into packages-launch
teemingc Sep 21, 2025
17c7595
remove little used routers
benmccann Sep 22, 2025
242bc62
add router from svelte faq
benmccann Sep 22, 2025
5c06311
move svelte-chartjs. lowercase titles
benmccann Sep 22, 2025
515cb55
remove unused field from registry
benmccann Sep 22, 2025
704b712
update sv add-ons title
benmccann Sep 23, 2025
7ea75ed
show some categories as alternatives to sveltekit functionality
benmccann Sep 23, 2025
a97e894
cleanup list of packages and descriptions
benmccann Sep 23, 2025
00868e5
better display of add-ons
benmccann Sep 23, 2025
22458b2
svelte-check
benmccann Sep 23, 2025
31a37d0
category descriptions
benmccann Sep 23, 2025
82cb0a4
update descriptions to mention tailwind
benmccann Sep 23, 2025
4f4e635
prettier
benmccann Sep 23, 2025
3a94e92
cleanup
benmccann Sep 23, 2025
acde235
scroll y
jycouet Sep 23, 2025
04805e7
Merge branch 'packages-launch' of github.com:sveltejs/svelte.dev into…
jycouet Sep 23, 2025
ce092fb
more cleanup
jycouet Sep 23, 2025
b2fdc27
add 2 missing json
jycouet Sep 23, 2025
b9cc49f
rmv unused json
jycouet Sep 23, 2025
0a221e4
update metadata
jycouet Sep 23, 2025
eb59c03
repo_rul back
jycouet Sep 23, 2025
1a1c02a
update metadata script
jycouet Sep 23, 2025
231c17c
Merge branch 'main' into packages-launch
teemingc Sep 24, 2025
2b1a418
update melt to new package
benmccann Sep 24, 2025
6d9812b
add testing and devtools section
benmccann Sep 24, 2025
6ed8629
i18n category
benmccann Sep 24, 2025
4d09c7f
cleanup media category
benmccann Sep 24, 2025
8895ce6
update metadata
jycouet Sep 24, 2025
214fcbf
rmv duplicate
jycouet Sep 24, 2025
287d73f
Merge branch 'main' into packages-launch
teemingc Sep 25, 2025
837e3ea
add links in descriptions
benmccann Sep 25, 2025
6115add
bug fix: don't mutate existing data
benmccann Sep 25, 2025
483001d
change wuchale to '@wuchale/svelte'
benmccann Sep 25, 2025
7c801bf
format
benmccann Sep 25, 2025
fb961a9
update browser extension listing
benmccann Sep 25, 2025
88802ae
remove a couple more entries
benmccann Sep 25, 2025
490bd6f
Merge branch 'packages-launch' of github.com:sveltejs/svelte.dev into…
jycouet Sep 26, 2025
e95b77b
update stats
jycouet Sep 26, 2025
c01a662
addin a report at the end
jycouet Sep 26, 2025
8584955
add github token (preparing action) & update stars
jycouet Sep 26, 2025
19b0e2a
add some reports
jycouet Sep 26, 2025
4f4610d
moving things around for stats & better understanding
jycouet Sep 26, 2025
47e0dc6
pretty
jycouet Sep 26, 2025
84b229a
update with svelte_range & kit_range
jycouet Sep 26, 2025
78a4238
stable order
jycouet Sep 26, 2025
73588f1
fetcher
jycouet Sep 26, 2025
b2827b2
address deprecations
benmccann Sep 26, 2025
cd7c37e
add sveltepress
benmccann Sep 27, 2025
2491346
no filter npm stats
jycouet Sep 27, 2025
d096f30
CI sync-packages v001
jycouet Sep 27, 2025
3f17a42
CI sync-packages v002
jycouet Sep 27, 2025
3c33d6f
CI sync-packages v003
jycouet Sep 27, 2025
28203cd
CI sync-packages v004
jycouet Sep 27, 2025
f0512b3
CI sync-packages v005
jycouet Sep 27, 2025
3f474e9
CI sync-packages v006
jycouet Sep 27, 2025
2b884a3
CI sync-packages v007
jycouet Sep 27, 2025
6cf1dd3
CI sync-packages v008
jycouet Sep 27, 2025
3bb55f1
CI sync-packages v009
jycouet Sep 27, 2025
3fdd8e1
CI sync-packages v011
jycouet Sep 27, 2025
4673561
update metadata
jycouet Sep 27, 2025
57f702b
adding a readme
jycouet Sep 27, 2025
3d94a1a
update stats
jycouet Sep 27, 2025
166a17d
switch to full ts first (description)
jycouet Sep 27, 2025
065ec62
better CRUD management
jycouet Sep 27, 2025
68b1d41
Don't use @html description (and strip out makdown links). Descriptio…
jycouet Sep 28, 2025
c6700f0
more package cleanup
benmccann Sep 29, 2025
51ac8c8
remove comment
benmccann Sep 29, 2025
4903fac
add deno sveltekit adapter
benmccann Sep 30, 2025
66c561b
reorder categories
benmccann Sep 30, 2025
ab85fe6
move ark down a few places out of the default viewport
benmccann Sep 30, 2025
04ba8cc
Update .github/workflows/sync-packages.yml
benmccann Sep 30, 2025
619d1af
Update .github/workflows/sync-packages.yml
benmccann Sep 30, 2025
a5bdc7a
update setup-node action
benmccann Sep 30, 2025
e7be61e
don't use tsx for new script
benmccann Sep 30, 2025
c755de9
add a link to sveltesociety
benmccann Sep 30, 2025
d3cc0d8
format
benmccann Sep 30, 2025
dab7641
more-less
jycouet Oct 1, 2025
af99bcb
tweak styles
Rich-Harris Oct 1, 2025
0e4c140
style tweaks
Rich-Harris Oct 1, 2025
fe0cf69
tweak
Rich-Harris Oct 1, 2025
f622bee
fix scroll
Rich-Harris Oct 1, 2025
7db7c1c
dark mode
Rich-Harris Oct 1, 2025
de61946
tweaks
Rich-Harris Oct 1, 2025
e2e491c
more useful title
Rich-Harris Oct 1, 2025
8eb152e
make the entire card a link
Rich-Harris Oct 1, 2025
08032ba
tidy up
Rich-Harris Oct 1, 2025
2f05761
tweak wording
Rich-Harris Oct 1, 2025
aa1ed61
move stuff to top
Rich-Harris Oct 1, 2025
5cc6a81
remove link to sveltesociety.dev
Rich-Harris Oct 1, 2025
d6406c2
add note
Rich-Harris Oct 1, 2025
76ac0f4
tweak styles
Rich-Harris Oct 1, 2025
038a857
unused
Rich-Harris Oct 1, 2025
15944db
design cleanup (#1568)
jycouet Oct 1, 2025
900d220
description overrides
benmccann Oct 1, 2025
c78510e
merge
Rich-Harris Oct 1, 2025
f783a19
use <details>
Rich-Harris Oct 1, 2025
b4ac581
Merge branch 'packages-launch' of github.com:sveltejs/svelte.dev into…
Rich-Harris Oct 1, 2025
2a3ba4d
tweak
Rich-Harris Oct 1, 2025
b6f1306
unused
Rich-Harris Oct 1, 2025
4a07942
sync script update
jycouet Oct 1, 2025
c6142cf
rmc dots at the end of desc
jycouet Oct 1, 2025
068d55e
cleanup description will not end by "." & links will not end with #re…
jycouet Oct 1, 2025
11f4013
update data
jycouet Oct 1, 2025
1156513
cursor: pointer all the way
jycouet Oct 1, 2025
1555565
always link
Rich-Harris Oct 1, 2025
c7861b5
omit links element for sv add-ons
Rich-Harris Oct 1, 2025
8637923
remove stats from sv add-ons
Rich-Harris Oct 1, 2025
be5bcce
more description updates
benmccann Oct 1, 2025
e8013a5
a few more descriptions
benmccann Oct 1, 2025
70feaae
logos
Rich-Harris Oct 1, 2025
4e77684
hack
Rich-Harris Oct 1, 2025
f316a39
Merge branch 'packages-launch-logos' into packages-launch
Rich-Harris Oct 1, 2025
3d535d8
fix playwright logo cropping
Rich-Harris Oct 1, 2025
38490ab
tweak some wording slightly
Rich-Harris Oct 1, 2025
e23cc5e
slim down some descriptions
Rich-Harris Oct 1, 2025
c11b9d0
lucia description
Rich-Harris Oct 1, 2025
fe47214
bunch more
Rich-Harris Oct 1, 2025
6720f3a
more
Rich-Harris Oct 1, 2025
503f8ae
more
Rich-Harris Oct 1, 2025
74c0498
more
Rich-Harris Oct 1, 2025
62b9249
more
Rich-Harris Oct 1, 2025
e83c328
fix lucide
benmccann Oct 1, 2025
c259d69
finish removing package
benmccann Oct 1, 2025
136da5f
more
Rich-Harris Oct 1, 2025
09bef26
Merge branch 'packages-launch' of github.com:sveltejs/svelte.dev into…
Rich-Harris Oct 1, 2025
d9cb37a
fix
Rich-Harris Oct 2, 2025
75847e2
focus ring on links
Rich-Harris Oct 2, 2025
30b9020
small tweak
Rich-Harris Oct 2, 2025
e18467a
fix
Rich-Harris Oct 2, 2025
293424a
text-decoration to make it clear it links
Rich-Harris Oct 2, 2025
b4c50fe
tweak
Rich-Harris Oct 2, 2025
1d64167
add permalink
jycouet Oct 2, 2025
9412126
sharing links are open
jycouet Oct 2, 2025
46c1913
rmv auto, add static, tweak order
jycouet Oct 2, 2025
609aaa8
semi
jycouet Oct 2, 2025
a33d4ff
sync packages
benmccann Oct 2, 2025
09e3979
remove kit-docs as unmaintained
benmccann Oct 2, 2025
186100b
remove amp package
Rich-Harris Oct 2, 2025
cf28cf9
Merge branch 'packages-launch' of github.com:sveltejs/svelte.dev into…
Rich-Harris Oct 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/sync-packages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Sync packages

on:
schedule:
- cron: '0 0 * * 0' # At 00:00 on Sunday.
workflow_dispatch: # Allow manual triggering

permissions:
contents: write
pull-requests: write

jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v5
with:
node-version: 24
- run: pnpm install --frozen-lockfile --ignore-scripts

- name: Sync packages
run: cd apps/svelte.dev && pnpm sync-packages
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Create or update pull request
uses: peter-evans/create-pull-request@599a7e63a6240886b1b61fe984db1de9e0b05bc4 # v7.0.8
with:
commit-message: 'chore(packages): Update metadata'
title: 'chore(packages): Update metadata'
body: Automatically fetch latest packages metadata from NPM & GitHub.
branch: ci/update-packages-metadata
delete-branch: true
4 changes: 3 additions & 1 deletion apps/svelte.dev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"check": "node scripts/update.js && svelte-kit sync && svelte-check",
"format": "prettier --write .",
"lint": "prettier --check .",
"sync-docs": "tsx scripts/sync-docs/index.ts"
"sync-docs": "tsx scripts/sync-docs/index.ts",
"sync-packages": "node scripts/sync-packages/index.ts"
},
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15",
Expand All @@ -40,6 +41,7 @@
"flexsearch": "^0.7.43",
"flru": "^1.0.2",
"icons": "workspace:*",
"logos": "workspace:*",
"port-authority": "^2.0.1",
"topojson-client": "^3.1.0",
"vitest": "^3.2.4",
Expand Down
6 changes: 3 additions & 3 deletions apps/svelte.dev/scripts/sync-docs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import path from 'node:path';
import fs from 'node:fs';
import { parseArgs } from 'node:util';
import ts from 'typescript';
import glob from 'tiny-glob/sync';
import glob from 'tiny-glob/sync.js';
import chokidar from 'chokidar';
import { fileURLToPath } from 'node:url';
import { clone_repo, migrate_meta_json } from './utils';
import { get_types, read_d_ts_file, read_types } from './types';
import { clone_repo, migrate_meta_json } from './utils.ts';
import { get_types, read_d_ts_file, read_types } from './types.ts';
import type { Modules } from '@sveltejs/site-kit/markdown';

interface Package {
Expand Down
2 changes: 1 addition & 1 deletion apps/svelte.dev/scripts/sync-docs/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { execSync, spawn, type SpawnOptions } from 'node:child_process';
import fs from 'node:fs';
import glob from 'tiny-glob/sync';
import glob from 'tiny-glob/sync.js';

export async function clone_repo(repo: string, name: string, branch: string, cwd: string) {
const dir = `${cwd}/${name}`;
Expand Down
19 changes: 19 additions & 0 deletions apps/svelte.dev/scripts/sync-packages/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# sync-packages

This script syncs the packages metadata from NPM & GitHub.

## Usage

```bash
pnpm sync-packages
```

## Notes

- All packages `names` are in `FEATURED` of [packages-meta.ts](apps/svelte.dev/src/lib/packages-meta.ts) file.

If you want to add or remove a package, you need to update `FEATURED` objects and run the script again (it will update the json files in the `src/lib/server/generated/registry` directory).

- [sync-packages.yml](/.github/workflows/sync-packages.yml) is responsible for running the script regularly and update all metadata (it can also be triggered manually).

- Ambassadors and maintainers are curating the list of packages.
280 changes: 280 additions & 0 deletions apps/svelte.dev/scripts/sync-packages/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
import { PACKAGES_META } from '../../src/lib/packages-meta.ts';
import type { PackageKey, PackageNpm, PackageGithub } from '../../src/lib/server/content.ts';
import { execSync } from 'node:child_process';
import fs from 'node:fs';
import path from 'node:path';
import process from 'node:process';

let skipGithubStars = false;

const start = performance.now();
console.log('[sync-packages] start');

let logsAtTheEnd: {
type:
| 'no_repo_url'
| 'low_downloads'
| 'low_github_stars'
| 'new_json_file'
| 'deleted_unused_json_file'
| 'outdated'
| 'deprecated'
| 'npm_error';
pkg: string;
extra: string;
}[] = [];

const packages = PACKAGES_META.FEATURED.flatMap((pkg) => pkg.packages).map((pkg) => pkg.name);

const registryFolder = 'src/lib/server/generated/registry';

// PART 1: create missing json files
for (const pkg of packages) {
const cleanPkg = pkg.replace('@', '').replace('/', '-');
const jsonPath = path.join(registryFolder, `${cleanPkg}.json`);
if (!fs.existsSync(jsonPath)) {
const p = await getNpmAndGitHubData(pkg);
writeJsonData(jsonPath, p);
logsAtTheEnd.push({ type: 'new_json_file', pkg, extra: `created -> ${jsonPath}` });
}
}

// PART 2: delete unused json files
let registryJsonFiles = fs.readdirSync(registryFolder);
const jsonUsed: string[] = [];
for (const pkg of packages) {
const cleanPkg = pkg.replace('@', '').replace('/', '-');
const cleanPkgFile = `${cleanPkg}.json`;
const jsonPath = path.join(registryFolder, cleanPkgFile);
if (fs.existsSync(jsonPath)) {
jsonUsed.push(cleanPkgFile);
}
}
const jsonNotNeeded = registryJsonFiles.filter((pkg) => !jsonUsed.includes(pkg));
if (jsonNotNeeded.length > 0) {
// delete json files
for (const pkg of jsonNotNeeded) {
const jsonPath = path.join(registryFolder, pkg);
fs.unlinkSync(jsonPath);
logsAtTheEnd.push({ type: 'deleted_unused_json_file', pkg, extra: `deleted -> ${jsonPath}` });
}

// Let's continue
// theEnd(1);
}

// PART 3: refresh data
registryJsonFiles = fs.readdirSync(registryFolder); //.slice(0, 20);

const batch = 10;
for (let i = 0; i < registryJsonFiles.length; i += batch) {
const batchFiles = registryJsonFiles.slice(i, i + batch);
await Promise.all(
batchFiles.map(async (pkg) => {
await refreshJsonFile(path.join(registryFolder, pkg));
})
);
}

theEnd(0);

// HELPERS

function theEnd(val: number) {
const msg = ['[sync-packages]'];
if (val > 0) {
msg.push(`exit(${val}) - `);
}
msg.push(`took: ${(performance.now() - start).toFixed(0)}ms`);
console.log(msg.join(' '));
if (logsAtTheEnd.length > 0) {
console.log('[sync-packages] report:');
const typePrints: Record<(typeof logsAtTheEnd)[number]['type'], string> = {
no_repo_url: 'No GitHub URL',
low_downloads: 'Low Downloads',
low_github_stars: 'Low Stars',
new_json_file: 'NEW JSON',
deleted_unused_json_file: 'DEL JSON',
outdated: 'Outdated',
deprecated: 'Deprecated',
npm_error: 'NPM Error'
};
console.log(
` - ${logsAtTheEnd.map((l) => `${typePrints[l.type].padEnd(15)} | ${l.pkg.padEnd(35)} | ${l.extra}`).join('\n - ')}`
);
}
process.exit(val);
}

async function getNpmAndGitHubData(pkg: string): Promise<PackageKey & PackageNpm & PackageGithub> {
const [npmInfo, npmDlInfo] = await Promise.all([
fetchJson(`https://registry.npmjs.org/${pkg}`),
fetchJson(`https://api.npmjs.org/downloads/point/last-week/${pkg}`)
]);

if (npmInfo.error) {
logsAtTheEnd.push({ type: 'npm_error', pkg, extra: npmInfo.error });
theEnd(1);
}

// delete npmInfo.readme;
// delete npmInfo.versions;
// console.log(`npmInfo`, npmInfo);

const npm_description = npmInfo.description;
const raw_repo_url = npmInfo.repository?.url ?? '';
const repo_url = raw_repo_url?.replace(/^git\+/, '').replace(/\.git$/, '');
if (!repo_url) {
// console.error(`repo_url not found for ${pkg}`);
logsAtTheEnd.push({ type: 'no_repo_url', pkg, extra: `not found` });
}
const git_org = repo_url?.split('/')[3];
const git_repo = repo_url?.split('/')[4];

const authors = npmInfo.maintainers?.map((m: { name: string }) => m.name);
const homepage = npmInfo.homepage;
const downloads = npmDlInfo.downloads;
const version = npmInfo['dist-tags'].latest;
const updated = npmInfo.time[version];
const pkgInfo = npmInfo.versions[version];
const deprecated_reason = pkgInfo.deprecated;

const svelte_range =
pkgInfo.peerDependencies?.svelte ??
pkgInfo.dependencies?.svelte ??
pkgInfo.devDependencies?.svelte;

const kit_range =
pkgInfo.peerDependencies?.['@sveltejs/kit'] ??
pkgInfo.dependencies?.['@sveltejs/kit'] ??
pkgInfo.devDependencies?.['@sveltejs/kit'];

// GitHub
let github_stars: number | undefined = undefined;
if (git_org && git_repo && !skipGithubStars) {
const token = process.env.GITHUB_TOKEN;
const headers = token ? new Headers({ authorization: 'Bearer ' + token }) : {};
const res = await fetchJson(`https://api.github.com/repos/${git_org}/${git_repo}`, { headers });
if (res?.message && res?.message.startsWith('API rate limit exceeded')) {
skipGithubStars = true;
} else {
github_stars = res.stargazers_count;
}
}

return {
name: pkg,
npm_description,
repo_url,
authors,
homepage,
version,
deprecated_reason,
downloads,
updated,
svelte_range,
kit_range,

// GitHub
github_stars
};
}

async function refreshJsonFile(fullPath: string) {
console.log(`Refreshing:`, fullPath);

const currentJson = JSON.parse(fs.readFileSync(fullPath, 'utf-8'));
const newData = await getNpmAndGitHubData(currentJson.name);

// remove all undefined values
for (const key in newData) {
if (newData[key] === undefined) {
delete newData[key];
}
}

// Let's not filter npm downloads changes
// // filter changes of downloads
// if (newData.downloads && currentJson.downloads) {
// const dlDelta = Math.abs(
// ((newData.downloads - currentJson.downloads) / currentJson.downloads) * 100
// );
// if (dlDelta < 2.5) delete newData.downloads;
// }

const data = { ...currentJson, ...newData };

// Some stats infos to log
if (data.downloads && data.downloads < 255) {
logsAtTheEnd.push({ type: 'low_downloads', pkg: data.name, extra: `${data.downloads}` });
}

if (data.github_stars && data.github_stars < 42) {
logsAtTheEnd.push({
type: 'low_github_stars',
pkg: data.name,
extra: `${data.github_stars}`
});
}

if (data.updated && PACKAGES_META.is_outdated(data.updated)) {
logsAtTheEnd.push({ type: 'outdated', pkg: data.name, extra: `${data.updated}` });
}

if (data.deprecated_reason) {
logsAtTheEnd.push({ type: 'deprecated', pkg: data.name, extra: `${data.deprecated_reason}` });
}

writeJsonData(fullPath, data);
}

function writeJsonData(path: string, data: any) {
const keysOrder: (keyof PackageKey | keyof PackageNpm | keyof PackageGithub)[] = [
'name',
'npm_description',
'repo_url',
'authors',
'homepage',
'version',
'deprecated_reason',
'downloads',
'github_stars',
'updated',
'svelte_range',
'kit_range',
'typescript',
'runes',
'last_rune_check_version'
];

const sortedData: Record<string, any> = {};
for (const key of keysOrder) {
if (data[key] !== undefined) {
sortedData[key] = data[key];
}
}
// all all the remaining keys
for (const key in data) {
if (!keysOrder.includes(key as keyof PackageKey | keyof PackageNpm | keyof PackageGithub)) {
sortedData[key] = data[key];
}
}

fs.writeFileSync(path, JSON.stringify(sortedData, null, 2));
execSync(`prettier --write ${path}`);
}

async function fetchJson(url: string, options: RequestInit = {}): Promise<any> {
const headers = new Headers({ ...options.headers, 'User-Agent': 'svelte.dev/packages_v0.0.1' });

for (let i = 0; i < 5; i++) {
try {
const res = await fetch(url, { ...options, headers });
return await res.json();
} catch (e) {
console.error(`Failed to fetch ${url} after ${i + 1} retries`);
}

await new Promise((resolve) => setTimeout(resolve, 1000 * Math.pow(2, i + 1)));
}
}
Loading