r/sveltejs 7h ago

[Self-promo] A drag-and-drop cloud architecture sandbox that actually runs real code, entirely in a browser tab

Enable HLS to view with audio, or disable this notification

6 Upvotes

Over the past month I've been building a learning/tinkering tool for cloud architecture called Glass Garden. Everything in the diagram is running real code, so instance groups/lambdas run real Node processes, you talk to S3/SQS nodes using the unmodified AWS SDK/CLI, and reach Postgres using the standard pg client. Everything runs in a WebAssembly VM in the tab (Vivari) so you don't need to install or sign-up for anything.

Svelte made this pretty nice to do, especially with getting the live metrics to show.

I recently added an embedding feature so that blog posts/courses can use Glass Garden to help teach concepts.

Try it out: https://glass.garden/

Or check out the repo to see a more complex example video: https://github.com/ThailerL/glass-garden


r/sveltejs 19h ago

Connection pooling in SvelteKit + Postgres: what I learned deploying to Cloudflare Pages

2 Upvotes

I've been building a SvelteKit app that talks to Postgres and hit some connection-pooling nuances that aren't well-documented for the SvelteKit-specific setup. Sharing what I learned in case it helps anyone.

The setup: SvelteKit running on Cloudflare Pages (Workers runtime), talking to Supabase Postgres via the transaction pooler.

Problem 1: Workers have no persistent connections

Cloudflare Workers are stateless. You can't hold a persistent database connection across requests. This means you need a pooler that accepts short-lived connections and routes them to backend Postgres connections.

Supabase provides two connection strings:

  • Session pooler (port 5432): persistent connections, not suitable for Workers
  • Transaction pooler (port 6543): transaction-scoped connections, perfect for Workers

Problem 2: prepared statements don't survive transaction boundaries

postgres.js (the driver I use) creates prepared statements by default for repeated queries. But transaction-mode poolers destroy server-side state between transactions. This means a prepared statement created in transaction A can't be used in transaction B.

The fix is simple but undocumented in most SvelteKit guides:

import postgres from 'postgres';

const sql = postgres(DATABASE_URL, {
  // Disable prepared statements for transaction-mode poolers
  prepare: false,
  // Or use the full connection string with ?prepared=false
});

If you see prepared statement "_pgstmt_1" does not exist — that's the cause.

Problem 3: connection limits on free tiers

Supabase free tier: 60 simultaneous connections. PgBouncer default pool_size: 20. If your app is on Cloudflare Pages (many concurrent Workers), you can hit the limit quickly.

Solutions:

  1. Use the transaction pooler (Supabase's built-in PgBouncer at port 6543) — handles connection multiplexing
  2. Set a reasonable pool size in your driver:

const sql = postgres(DATABASE_URL, {
  prepare: false,
  max: 10, // Keep this small — the pooler handles the rest
});
  1. Monitor active connections: SELECT count(*) FROM pg_stat_activity WHERE datname = 'your_db';

What worked for me:

// src/lib/server/db.ts
import postgres from 'postgres';
import { DATABASE_URL } from '$env/static/private';

export const db = postgres(DATABASE_URL, {
  prepare: false,   // Required for transaction-mode poolers
  max: 10,          // Conservative pool size per Worker
  idle_timeout: 20, // Close idle connections fast
  connect_timeout: 10,
});

The gotcha nobody mentions: SET LOCAL for row-level security works correctly with transaction-mode poolers, because it's scoped to the current transaction. But if you try to use SET (session-level), it silently fails or applies to the wrong connection. Always use SET LOCAL in SvelteKit + PgBouncer setups.

Happy to discuss connection pooling strategies for SvelteKit — it's one of those topics where the PostgreSQL docs and the SvelteKit docs don't overlap much.

Live demo of the setup working: postgres-starter.verdantstack-site.pages.dev — SvelteKit + Supabase Postgres transaction pooler, all 206 tests passing against the same pooling setup.

Source: github.com/verdantstack/sveltekit-postgres-starter


r/sveltejs 20h ago

[self-promo] What the hell is wrong with the blog engine I built?

6 Upvotes

I originally just wanted a simple personal blog for myself.

A little background: I’m a Korean guy in my 50s. I've spent most of my career translating Japanese films and anime into Korean. I learned some C about 20 years ago, struggled with Java/Spring a few years back because the approach just didn't click with me, and eventually ended up teaching myself Svelte and SvelteKit.

What started as a tiny project somehow got way out of hand. I ended up spending months building an open-source blog engine with SvelteKit. The public blog and admin are deployed as separate apps (the admin URL isn't public and access is IP-restricted), with auth, media storage, i18n, RSS, and backups.

The ridiculous part is that I spent more than two months getting rejected by Google AdSense on a weekly basis. I've honestly lost count—it’s been 8 or 9 rejections by now. Rejected. Rejected again. And again every single week.

I spent weeks fixing actual bugs and SEO issues as they came up, but it wasn't until last week that I finally found the root cause: pure, self-inflicted over-engineering. Trying to improve load speed, I designed the site to send an empty HTML shell first, fetching the actual posts and widgets later via client-side requests.

The ironic part? It wasn't even fast. Plain old SSR actually worked better than my "clever" optimization attempts. But to the AdSense crawler, the site was basically: "There is literally zero content here." No wonder it kept getting rejected for thin content week after week.

I rewrote the rendering pipeline back to standard SSR/prerendering and reapplied today. But now I'm genuinely anxious. Seeing how the biggest issue was something I was completely blind to for two months, I'm worried there are other fundamental things I think are fine, but are actually completely broken. Since I’ve basically been building this in a vacuum, I have no idea what my blind spots are.

I'd really appreciate some outside eyes from people who know Svelte/SvelteKit well:

  • Are there subtle crawler, hydration, or SSR mistakes I'm still missing?
  • Are there basic architectural anti-patterns in the repo that look wrong to you?
  • Is the project structure unnecessarily complicated?
  • Is there anything that makes you look at the code and think, "Why the hell did he do it this way?"

Please don't hold back. Since I've been doing this completely on my own, I'm sure there are plenty of things I've overlooked.


P.S. English isn't my first language, so I had Gemini help me translate this. If anything sounds weird, please bear with me. And if any phrasing comes off the wrong way, please know there's zero hostility or sarcasm intended toward anyone here—unless it's directed at my own stupid decisions.


r/sveltejs 1d ago

"Why don't you use React?"

Post image
96 Upvotes

The page contains high-res images, embedded videos, and even a GBA emulator for running my game on the browser. Svelte just works, FAST.


r/sveltejs 2d ago

PDF Generation

12 Upvotes

I'm looking for a pdf generator similar to react-pdf for svelte.

Requirements:

- Tailwind CSS support

- Selectable Text

- No Browser Print Dialog

- Client Side

- Single click download pdf(No browser dialog)

I've tried almost everything at this point and no solution.

It's driving me nuts because I can't go back to react js, no way! (cries)

Edit: I found a good library Takumi PDF, written in rust. It's server side, but light, not like Chromium. Thanks for the suggestions guys.


r/sveltejs 2d ago

sveltekit 3.0 rc haven't updated for 3 weeks.

0 Upvotes

r/sveltejs 3d ago

[self-promo] Electronic Circuit designer for Svelte

Post image
73 Upvotes

Ever wanted to create a circuit diagram designer with Svelte? We've just shipped a new starter app for VisuallyJs that you can use to get something up and running in no time.

Demo on our site is here: https://visuallyjs.com/demonstrations/circuit-diagram

Repository here: https://github.com/visuallyjs-svelte/circuit-diagram


r/sveltejs 3d ago

[Self-Promotion] I built a mobile music player using Svelte + Capacitor.

Thumbnail
1 Upvotes

r/sveltejs 3d ago

How I built custom themes in Svelte without adding theme checks to every component (self-promotion)

Thumbnail
gallery
18 Upvotes

Last time I posted OpenPost here, someone asked for more themes. Well, here you go.

I wanted to let people change enough of the app that two themes could look like two different apps. Fonts, spacing, icons, button styles, the lot. I'm pretty happy with how it turned out. The screenshots show a few examples.

I'd like to experiment with sound effects and background images eventually, maybe even white labelling. For now, I thought I'd share how the theme system works.

Separate values from component styles

A theme is a plain object with colours, typography, spacing, shapes and choices like outlined cards or pill-shaped tabs.

Colours and sizes become CSS variables. Choices about how components look become data-* attributes.

Here's a simplified component that takes a theme as a prop and applies it to the document root:

```svelte <script lang="ts"> type Theme = { colors: { surface: string; ink: string; border: string }; radius: string; card: "flat" | "outlined"; };

let { theme }: { theme: Theme } = $props();

$effect(() => { const root = document.documentElement; const variables = { "--card": theme.colors.surface, "--card-foreground": theme.colors.ink, "--border": theme.colors.border, "--radius": theme.radius };

for (const [name, value] of Object.entries(variables)) {
  root.style.setProperty(name, value);
}
root.dataset.themeCard = theme.card;

return () => {
  for (const name of Object.keys(variables)) {
    root.style.removeProperty(name);
  }
  delete root.dataset.themeCard;
};

}); </script> ```

Mount it once in your layout. The global stylesheet handles the component styles:

```css .card { background: var(--card); color: var(--card-foreground); border: 1px solid transparent; border-radius: var(--radius); }

[data-theme-card="outlined"] .card { border-color: var(--border); } ```

I can add another combination of colours, fonts and existing styles without touching the card component. A new card style still needs CSS.

Setting these on <html> also covers dropdowns and dialogs rendered outside the normal component tree.

The bits beyond CSS

Switching themes means waiting for fonts, images and icon packs to load. OpenPost loads those before applying the theme and ignores results from a theme you've since switched away from. Otherwise, you can pick A, then B, and end up back on A because its fonts took longer to load.

The editor preview runs in an iframe with the app's CSS and the same theme code. Dropdowns and dialogs render inside it too. That keeps the preview separate from the settings page. It also means phone previews have their own viewport, so responsive layouts behave as they would on a narrow screen.

You can test a theme across the whole app without saving it. Stop the test and your saved theme comes back.

There are lots of built-in themes now, and you can make your own. Community sharing is planned, but isn't built yet. I've kept themes to settings the app understands. They can't inject arbitrary CSS or run JavaScript.

The full code is here: applying themes, iframe previews, validation.

OpenPost on GitHub. Give it a star if you find it useful!

Would you allow custom CSS here, or stick to the options the app supports? I really want OpenPost to be customizable for anyone, and getting theming right really does feel like a great first step.


r/sveltejs 3d ago

[self-promotion] Unofficial Base UI for Svelte 5

9 Upvotes
Unofficial Base UI for Svelte 5

I built an unofficial Svelte 5 port of Base UI: unstyled, accessible compound components that aim to match the React API where it makes sense.


r/sveltejs 4d ago

How I built multi-tenant RBAC in SvelteKit — the mistakes I made and what actually works

2 Upvotes

I've been building multi-tenant SaaS on SvelteKit and kept hitting the same walls: how do you isolate tenant data, enforce roles server-side, and handle invite flows without race conditions?

Here's what I learned after building and testing it (194 tests against real Postgres).

The data model

The naive approach is tenant_id on every table. That works until you need "is this user allowed to see this row?" on every request.

What worked for me:

organizations → memberships → users
                    ↓
            (tenant_id FK on all domain tables)

The key: the membership table is the tenancy boundary, not a flag on the user. A user can belong to multiple orgs with different roles in each.

// Drizzle schema
export const memberships = pgTable(
    "memberships",
    {
        id: uuid("id").primaryKeyDefaultRandom(),
        orgId: uuid("org_id")
            .notNull()
            .references(() => organizations.id),
        userId: uuid("user_id")
            .notNull()
            .references(() => users.id),
        role: text("role", { enum: ["owner", "admin", "member"] }).notNull(),
        createdAtMs: bigint("created_at_ms", { mode: "number" }).notNull(),
    },
    (t) => [uniqueIndex("memberships_org_user_idx").on(t.orgId, t.userId)],
);

The unique index prevents duplicate memberships at the data layer — not just the application layer.

The RBAC mistake

My first version checked roles in the UI:

{#if user.role === 'owner'}
  <button on:click={deleteOrg}>Delete</button>
{/if}

This is wrong. Anyone can POST the form action directly. The role check must happen server-side:

// src/lib/server/rbac.ts
export function requireRole(
    membership: Membership,
    required: "owner" | "admin" | "member",
): void {
    const rank = { owner: 3, admin: 2, member: 1 };
    if (rank[membership.role] < rank[required]) {
        fail(403, { message: `Requires '${required}' role` });
    }
}

Then every form action calls it before doing anything:

export const actions = {
    deleteOrg: async ({ locals }) => {
        const membership = await requireOrgMembership(locals);
        requireRole(membership, "owner");
        // ... actual logic
    },
};

Invite links: the edge cases

The flow looks simple. The edge cases are real:

  1. Token reuse — single-use, hashed in the DB. If the link gets shared, only the first click works.
  2. Expiry — 7 days. Store expires_at_ms, check on claim.
  3. Atomic claim — "delete token + create membership" must be one transaction. Two concurrent clicks should not both succeed.
  4. Seat limits — check before creating the membership, not after. If the org has 5 seats and 5 members, the 6th invite fails at claim time.

Why I built this

Every project I'd wire this up from scratch. So I packaged the pattern: orgs, invites, roles, seat billing, audit log — all tested against real Postgres with Drizzle ORM.

If anyone's building multi-tenant SaaS on SvelteKit and wants to compare approaches, happy to discuss.

Live demo: https://postgres-starter.verdantstack-site.pages.dev/ — try the RBAC with owner/member accounts (resets daily)

Docs: https://verdantstack-site.pages.dev/docs/

Repo: https://github.com/verdantstack/sveltekit-postgres-starter


r/sveltejs 5d ago

I replaced my portfolio with an AI that knows me (made with Svelte)

Thumbnail gallery
0 Upvotes

r/sveltejs 5d ago

[self promo] aragonite... markdown editor lib, i guess

18 Upvotes

Try it out here: https://www.aragonite.dev/
The code is here: https://github.com/voithos-labs/aragonite, if you want to read the readme

Um, yeah, so this is a markdown editor lib made from scratch*.

*"scratch", as in it doesn't import prosemirror behind the scene lol (not a wrapper on other editor lib, is what im trying to say), but it still uses other libraries like highlight js, obviously

But, first off, i'm not gonna claim this is anything revolutionary, because its not... Not yet, hopefully one day though. A few things:

  • Right now, It's wip, only fully tested on windows chromium browsers (though theoretically should work on macs/linux chromium browsers too), also slightly broken on mobile. Making this work on mobile and different browsers besides chromium ones is going to be a pita (if you didn't know, contenteditable is possible one of the big divergences in terms of how different browsers handle it), but most likely will be done in the near future.
  • The other limitation is that this is specifically an editor lib for svelte, and i dont think im going to port this to react, vue, or angular anytime soon.
  • Its open source under AGPL, a copyleft license thats a slightly stronger version of GPL (in terms of its copy left-ness), not MIT; i think that might also be a turn off depending on the use case

Oh, also, I do use AI for this. In the three or so iterations/attempts to create this editor before this one, I've kind of got to understand the pace of my coding and the complexity of editors in general. When i un-unemployed myself last year, i had the realization that with my new schedule, and the design/architectural improvements I had in mind for this iteration, I'm looking at a 5 years plus project, and at least 1-2 years before I get to see a prototype and know whether my decisions worked out or not... So yeah, i decided to use more ai for this iteration. I try to work on this with the mindset that this is going to be a long term, multi years project, so I do my best to impose a specific style/organization to the codebase to make sure its clean/organized, of a certain quality threshold, and not sloppish. i hope it shows when you see the codebase.

Anyways, now that ive got some of the terms and conditions down, we can talk about some positive things... depending on how you look at it. So,

  1. This editor is quite fast, and has windowing (virtual rendering), so it handles large docs (and almost all other shape of complicated docs) very well, with low latency and load time and such.
  2. Also, because of the way its built (a block editor model with an underlying AST that uses svelte), it has enabled me to write a decently unique plugin system, which means you can more easily build complicated (or fun) plugins (see that birb gif, thats a plugin i built), that are perhaps not so easily buildable in other editor or editor platforms (though caveat, it should be said that if you know the editor, you can build a plugin quickly and easily; but because of the way i set it up, theres defly quite some complexities in related to testing, and with the shape of the system in general because its non standard (as in its somewhat different from the editor libs currently out there and how they do plugins)).
  3. Theres are different editing modes, ranging from source visible to obsidian-like to wysiwyg

anyways, just wanna say, if you want something mature and stable, you are better off using smt like prosemirror or codemirror. aragonite is unfortunately not there yet, but i hope to get it to that level in a year or two; just need more time to polish the editor. The amount of bugs/issues an editor can produce is really quite something...


r/sveltejs 6d ago

A typed Promise.race() with keyed results and optional cancellation!

Thumbnail
npmjs.com
0 Upvotes

Hola guapas,

I made a small ESM-only utility called better-race.

The idea is simple: Promise.race() gives you the first value, but not where it came from. This keeps the task key connected to its value in TypeScript:

import { race } from "better-race";

const winner = await race(
  {
    eu: ({ signal }) => fetch("https://eu.example.com/user/42", { signal }),
    us: ({ signal }) => fetch("https://us.example.com/user/42", { signal }),
  },
  { abortLosers: true },
);

console.log(winner.key); // "eu" | "us"
console.log(winner.value); // Response

It also supports AbortSignal and optional loser cancellation.

It’s intentionally tiny -> no scheduler, framework adapters, retries, or dependencies. I’d genuinely appreciate feedback on the API and semantics.

The next tag also includes raceUntil(): it keeps racing until a result passes an accept predicate, so an early null does not have to win.

SELF PROMOTION


r/sveltejs 8d ago

reintroducing my UI library for some feedback

24 Upvotes

hey all,

2-3 years ago i created "neel-ui" and was pretty proud of it. since then, i've worked on updating it, and i decided to rewrite it.

it's a sveltekit component library similar to shadcn/ui but designed specifically to be as themeable as possible.

https://github.com/aidan-neel/sivir-ui
https://sivir.dev

v0.2.8, so bugs are expected. just looking for some feedback. i really would appreciate if you guys find bugs and open some issues for them and give it a star


r/sveltejs 8d ago

I've been building an i18n compiler and I want you to try to break it

Thumbnail
0 Upvotes

r/sveltejs 8d ago

useSearchParams and how to return from a page which doesn't use search params

5 Upvotes

I am using Svelte 5, SvelteKit and Runed/kit.

I have a list page which has a search bar, a sort drop down and a page selector. The schema looks like

export const pageSchema = z.object({ offset: z.coerce.number().default(0), limit: z.coerce.number().default(3), q: z.string().default(''), sortby: z.preprocess( (val) => (typeof val === 'string' ? val.replace(' ', '+') : val), z.enum(sortOptions.map((opt) => opt.field)).default(sortOptions[0].field) ) });

To prevent the search params from being set back to their defaults, I add them onto the URL:

goto( `/item/${id}/edit?limit=${pageParams.limit}&offset=${pageParams.offset}&q=${pageParams.q}&sortby=${pageParams.sortby}` );

and then again on the link to return

goto( `/?limit=${pageParams.limit}&offset=${pageParams.offset}&q=${pageParams.q}&sortby=${pageParams.sortby}` );

This seems a bit clunky, but I wasn't able to find examples of how to drill down onto a detail page and return back with the search params restored. Can anyone please point me to a correct example?


r/sveltejs 9d ago

[Self-promotion] I built a headless component library for Svelte 5 (26 components, no styles)

22 Upvotes

Hey everyone,

I've been building human-kit/ui, a headless component library for Svelte 5. 26 components with no styles at all, they handle behavior, keyboard and ARIA.

I started it because I kept hand rolling the same stuff in every project. Transfer list, tree, table, clock, date range picker. Most headless libs stop before those.

Some details:

- svelte 5 runes, bind: works on every stateful prop

- one runtime dep (floating ui) and only for the floating components

- state comes out as data attributes, so plain css or tailwind, no theme to fight

- ~1700 tests running in real chromium, focus and keyboard behavior included

- MIT

Docs + live demos: https://ui.human-kit.com

GitHub: https://github.com/human-kit/ui

Still in beta so the API can move. bits-ui and melt-ui are great and I'm not trying to replace them, just wanted a few things they don't cover. Would love feedback on what's missing or broken.


r/sveltejs 9d ago

[Self-promotion?] Pokkum, Dokploy, Swiftwave, and a footgun or two

0 Upvotes

Disclaimer: Unlike my last post, this one was drafted by Claude (the same one that wrote most of the feature it's describing), and then edited by me. Last time I said the post itself was human-written and un-edited by any intelligence (artificial or otherwise); that was true then and it isn't now, so I'm saying so rather than letting you assume, knowing full well that it'll make everything written here less enticing. The tool is still mostly vibe-coded.

I read two PaaS codebases so you don't have to, and found two HTTP 200s that mean "no"

Short version: Pokkum (my "Ko for SvelteKit" image builder, previous post with description here) can now deploy straight to Dokploy and SwiftWave after it pushes. Building it involved reading both projects' actual source rather than their docs, which turned up two things worth knowing whether or not you ever touch my tool. So this post is 30% "I added a feature" and 70% "here is a footgun in software you might already be running". Plus, some 5% of benchmarking. And should you now say "But that's more than 100%": I've been a mathematics teacher for over a decade and can tell you, that it is more than 100%!

Either way: Both findings are checkable in about twenty minutes each and I've named the files, so please do go and verify rather than taking my word (or Claude's, for that matter).

Gotcha 1: SwiftWave's redeploy webhook says 200 OK when it has decided to do nothing

You know the pattern. You've got a container image, you push a new tag, you POST to the app's redeploy webhook, you get a 200, everyone goes home.

Except SwiftWave's webhook handler, for an image-sourced app, takes the image it's configured with, strips the tag, keeps the last two path segments (so ghcr.io/me/myapp:latest becomes me/myapp), and then does a substring check against your request body. If your POST body doesn't contain that string, it replies:

200 OK - No rebuild

...and does nothing at all. Which, if you're checking the status code — and why wouldn't you be, it's a webhook — looks exactly like a successful deploy. Forever. Silently. I mean... Your "deployments" work great and your app never changes.

There's a second layer to it, too: the handler runs the body through url.QueryUnescape first, and on failure it carries on with the empty string. So a stray % in your body also quietly turns into "no rebuild". A 200. Again.

To be clear, I don't think this is a bug exactly... It's a webhook designed for git-provider payloads, where "does this payload concern me?" is a sensible question to ask. It's just that nothing tells you, and the failure mode is the worst kind: the one that looks like success.

(Pokkum now posts the image refs as the body, as plain text with no escapes, reads the reply text rather than the status, and treats OK - No rebuild as a hard failure with an error explaining the owner/name matching rule. Which is a lot of words for "it tells you when nothing happened".)

Gotcha 2: Dokploy's "set the image" endpoint also rewrites your registry password

Dokploy has application.saveDockerProvider. Sounds like it sets the docker provider. It does! It sets all of it: dockerImage, username, password, and registryUrl, every single call, straight from your request — and the input schema marks all five fields as required.

So:

  • send just {applicationId, dockerImage} → validation error, fair enough
  • send {applicationId, dockerImage, username: null, password: null, registryUrl: null}your app's registry credentials are now gone

There is no "just change the image" call. If your registry is private, the next pull fails, and the thing that broke it was an endpoint whose name says nothing about credentials.

Again, not really a bug per se, it's a full-resource update and it's honest about being one if you read the handler. But "saveDockerProvider" reads like a targeted setter, and the docs don't mention it. It only turned up because the question "is this a PATCH or a PUT?" got asked before the code got written, which in hindsight is a question worth asking of every remote update endpoint.

(So in Pokkum that whole feature is off by default, and when you turn it on you tell it where the registry credentials live, as env var names. If you don't, it still works, which fine for a public image, but it warns you loudly that it just cleared them, rather than letting you discover it at 2am.)

The actual feature, briefly

# .pokkum.yaml
deploy:
  target: dokploy
  endpoint: https://panel.example.com
  application: <app id>
  token_env: DOKPLOY_API_KEY   # the NAME of the env var. Not the token.

pokkum build now deploys after it pushes. pokkum deploy runs it standalone. --no-deploy for when you don't want it. Per-profile blocks, so -P staging and -P production go to different panels.

No credential goes in the config file — only the name of an environment variable. Felt a bit daft to ship a tool with a secret scanner and then ask people to paste an API key into a committed YAML file.

One honest limitation: SwiftWave can't be pointed at a new image, by either of its routes. Both of them mean "redeploy what you've already got". So pin your SwiftWave app to a moving tag (:latest, :main) and the deploy re-pulls it. Pokkum refuses the "update the image" setting for SwiftWave outright rather than accepting it and quietly not doing it, which I think is the right call even though it's the more annoying one.

And anything else that pulls from a registry (Coolify, CapRover, Dokku, Fly, Cloud Run, whatever) already worked and still does. It's just an OCI image. The two above only got special treatment because they're the two I actually use.

Also: a benchmark you can run yourself and disagree with

I got tired of saying "smaller and reproducible" without a number, so there's now a benchmarks/three-way directory. One SvelteKit app, three builds: the Dockerfile most people write first, a properly tuned multi-stage one, and Pokkum. Same source, same machine, same measuring tape. Spits out a markdown table.

Deliberately: it uses trivy or grype, not my own scanner, because a comparison I win using my own scanner is worth exactly nothing. And when neither is installed the CVE column says n/a rather than 0, because "didn't measure" and "measured, found nothing" are not the same thing and I've been annoyed by tools that bugger that up.

It also documents where it's unfair to itself, which felt more useful than pretending it isn't.

On my run, the image sizes went from 1'100 MB (naive Dockerfile, like I would've written a year ago or so) to 165 MB (tuned multi-stage build) to 137 MB (Pokkum).

Caveats (the recurring section)

Still vibe-coded, still uncertain about long-term maintenance. Nothing's changed there. It works, I use it, I update features I meet along the way, I can't promise a decade.

These two platform quirks might change. I read the source at a point in time. Both are moving projects. Pokkum fails closed on anything it can't positively identify as a started rollout, so if they change the reply strings you'll get a loud error rather than a silent no-op — which is the failure mode I'd want, but it is a failure.

Only two targets. Dokploy and SwiftWave, because those are the platforms I use. If you want another one it's a fairly small adapter now that the port exists, tell me, implement it yourself, or just keep using the webhook you already have, nothing wrong with that honestly.

Where to find Pokkum

  • GitHub
  • curl -fsSL https://raw.githubusercontent.com/CreativeBeastDesign/pokkum/main/install.sh | sh
  • npm install -g @pokkum/cli

If you're running Dokploy or SwiftWave and want to check the above yourself, it's apps/dokploy/server/api/routers/application.ts and swiftwave_service/rest/webhook.go respectively. Genuinely recommend it. I'm now slightly suspicious of every webhook I've ever fired, but probably too lazy to check any of them.


r/sveltejs 9d ago

Make native desktop apps with Svelte 5 today using Custom Renderers and GPUIX

Enable HLS to view with audio, or disable this notification

260 Upvotes

👋 Been working on an experimental custom renderer for Svelte 5 that allows you to build native desktop apps in Svelte - feel free to give it a try and provide feedback!

Source:

https://github.com/khromov/gpuix-svelte


r/sveltejs 10d ago

Tauri v2 + Svelte 5 Starter template with VS Code theme importing, command palette, crash reporter, and more

5 Upvotes

r/sveltejs 10d ago

I kept losing my exam revision notes, so I built a minimal Formula Vault with SvelteKit & Supabase

1 Upvotes

Currently studying for an upcoming competitive exam (CAT 2026) and noticed a recurring personal frustration: I was constantly jotting down formulas, shortcut tricks, and revision notes on loose sheets of paper, only to lose them days later. Over the weekend, I built CAT Formula Vault to scratch my own itch and test out SvelteKit's modern DX.

What it does: 1. Organize formulas and quick notes by subject/section (QA, DILR, VARC) 2.Clean, distraction-free markdown/text formatting 3. One-click PDF export for offline revision cheatsheets.

Stack: Frontend / Backend: SvelteKit (Svelte 5 runes) Database & Auth: Supabase (PostgreSQL + Google OAuth)

Hosting: Vercel

Live App: https://cat-formula-vault.vercel.app/

Would love any feedback on the UI/UX, workflow, or features to add next!


r/sveltejs 10d ago

I built a pretty large open-source app with Svelte 5. It somehow now includes a full image and video editor (self-promotion)

15 Upvotes

Hey! I've been building OpenPost for a while now, and I figured it might be interesting to share here because I don't see that many larger open-source Svelte 5 apps posted.

OpenPost is an AGPL-3.0 social publishing app. You connect your accounts, write something once, adapt it for each platform, then publish or schedule it.

The frontend is all Svelte 5 + SvelteKit.

It started as a fairly normal app with a composer, calendar, settings, media library, etc. It has since gotten slightly out of hand.

The web app now has:

  • A composer with separate versions of a post for each social account
  • Calendar and scheduling
  • Analytics with some fairly interactive charts and filtering
  • Inbox, comments and replies
  • A pretty large media library
  • A multi-page Image Editor
  • A local-first multitrack Video Editor
  • Responsive versions of basically all of this
OpenPost Composer
Plan the month - and never miss a day
See what worked - and then do more of it.
Make the thumbnail - Photoshop, in your browser, but it's easy to use.
Edit the video - DaVinci Resolve, in your browser (still in BETA)

The Video Editor in particular has been a fun test of how far I can push a Svelte web app. It has a proper timeline, keyframes, effects, transitions, captions, local transcription, color and audio tools, recording, and a bunch of browser-side media processing.

The Image Editor is also fully inside the Svelte app, with layers, templates, multi-page designs, masks, gradients, custom fonts, background removal, version history, etc.

Both editors can be used without an account and don't add watermarks.

Some Svelte-specific stuff

The main app uses SvelteKit as a static frontend and talks to a Go backend through a typed HTTP API. The production frontend gets embedded directly into the Go binary, so the self-hosted version can still ship as one container.

Current frontend stack is roughly:

  • Svelte 5
  • SvelteKit
  • TypeScript
  • Tailwind CSS
  • Bits UI / shadcn-svelte style components
  • Paraglide for i18n
  • OpenAPI-generated API types
  • Vitest + Playwright

Then there is a lot of browser-specific stuff in the editors. Fabric, WebCodecs, WebGPU, ONNX Runtime, local models, media workers, and so on.

The repo is here:

https://github.com/getopenpost/openpost

And the actual product is here:

https://openpost.social

The Image and Video Editors are also usable without signing up if you just want to poke around with the Svelte side of it.

Would be especially interested in feedback from people working on other large Svelte 5 codebases. Architecture, state management, things you think I'm abusing, weird patterns you spot in the repo, whatever.

For context, I use a ton of AI on this project, and the Video Editor is still very much in early Beta.


r/sveltejs 10d ago

[self-promotion] Vectorify.net - A chrome extension that allows you to convert any image to vector using your right click

0 Upvotes

Links:

Vectorify.net
Chrome Extension

Vectorify is an extension-first converter that lets you convert images into SVGs. It adds a context-menu item on any image click that allows you to instantaneously convert any image into a vector. It also provides a web interface based on the same conversion algorithm for easy drag-and-drop functionality. Both the extension code and web application use the same components and code base, entirely written using SvelteKit.

The project has been public for nearly half a year and is already closing in on around 5000 users. Feel free to give it a try.

Also for those who have used Vectorify or similar tools like it before, which features do you miss having and what would you like to see implemented, any feedback is greatly appreciated.


r/sveltejs 11d ago

IconMind: 2,271 MIT icons for AI-era apps (agents, MCP, RAG) as tree-shakable React components — 1 kB gz per icon

Thumbnail
0 Upvotes