Skip to main content

Python backend, SvelteKit frontend, zero boilerplate in between.

Project description

FluidKit

FluidKit Logo
Web development for the Pythonist

FluidKit bridges Python and SvelteKit into a unified fullstack framework. Write backend functions in Python — FluidKit registers them as FastAPI endpoints and wraps them in SvelteKit-native remote functions with full type safety, cookie forwarding, file uploads, redirects, and single-flight cache invalidation.

pip install fluidkit

How it works

Decorate Python functions. FluidKit registers them as FastAPI endpoints internally and generates colocated .remote.ts files that SvelteKit imports as remote functions directly.

# src/lib/demo.py
from fluidkit import query, command, form

db = {
    "posts": [
        {"id": 1, "title": "Hello World", "content": "This is the first post.", "likes": 10},
        {"id": 2, "title": "Fluidkit", "content": "Fluidkit is awesome!", "likes": 50},
        {"id": 3, "title": "Python and Svelte", "content": "Using Python with Svelte is great!", "likes": 25},
    ]
}

@query
async def get_posts():
    return db["posts"]

@command
async def like_post(post_id: int):
    for post in db["posts"]:
        if post["id"] == post_id:
            post["likes"] += 1

            # invalidates client cache in the same request with single flight mutations
            await get_posts().refresh()
            return True
    return None

@form
async def add_post(title: str, content: str):
    new_post = {
        "id": len(db["posts"]) + 1,
        "title": title,
        "content": content,
        "likes": 0,
    }
    db["posts"].append(new_post)

    await get_posts().refresh() # invalidates client cache in the same request with single flight mutations
<!-- src/routes/+page.svelte -->
<script>
    import { get_posts, like_post, add_post } from '$lib/demo.remote';
</script>

<form {...add_post}>
  <input {...add_post.fields.title.as('text')} placeholder="Title" />
  <input {...add_post.fields.content.as('text')} placeholder="Content" />
  <button>Add Post</button>
</form>

{#each await get_posts() as post}
  <div>
    <h2>{post.title}</h2>
    <p>{post.content}</p>
    <button onclick={async () => await like_post(post.id)}>
      👍 {post.likes}
    </button>
  </div>
{/each}

No manual fetch calls. No duplicated types. No glue code.

🤫 how does this work? FluidKit reflects on your decorated functions at import time — inspecting parameters, return types, and Pydantic models — and generates colocated `.remote.ts` files wrapping each function in a SvelteKit-native `query`, `command`, `form`, or `prerender` remote function call. In dev mode this re-runs on every save via HMR. The generated files are real TypeScript you can inspect, import, and version control.

Decorators

Decorator Use case SvelteKit docs
@query Read data — cached, refreshable query
@command Write data — single-flight cache invalidation command
@form Form actions — file uploads, progressive enhancement, redirects form
@prerender Build-time data fetching with optional runtime fallback prerender

CLI

fluidkit init                # scaffold SvelteKit project with FluidKit wired in
fluidkit dev                 # run FastAPI + Vite together with HMR
fluidkit build               # codegen + npm run build
fluidkit preview             # preview production build locally

No system Node.js required — FluidKit uses nodejs-wheel for all Node operations. npm, npx, and node are available through the CLI:

fluidkit install tailwindcss          # shorthand for npm install
fluidkit install -D prettier          # install as dev dependency
fluidkit npm run build                # any npm command
fluidkit npx sv add tailwindcss       # any npx command
fluidkit node scripts/seed.js         # run node directly

Project config

// fluidkit.config.json
{
  "entry": "src/app.py",
  "host": "0.0.0.0",
  "backend_port": 8000,
  "frontend_port": 5173,
  "schema_output": "src/lib/fluidkit",
  "watch_pattern": "./*.py"
}

NOTE: Flags override config. Config overrides defaults.

Built with

  • SvelteKit — frontend framework with remote functions
  • FastAPI — API layer and request handling
  • Pydantic — type extraction and validation
  • Jurigged — hot module reloading in dev mode
  • nodejs-wheel — bundled Node.js, no system install needed

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fluidkit-1.0.5.tar.gz (43.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fluidkit-1.0.5-py3-none-any.whl (51.2 kB view details)

Uploaded Python 3

File details

Details for the file fluidkit-1.0.5.tar.gz.

File metadata

  • Download URL: fluidkit-1.0.5.tar.gz
  • Upload date:
  • Size: 43.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.30

File hashes

Hashes for fluidkit-1.0.5.tar.gz
Algorithm Hash digest
SHA256 ae52386fb5f3b2c207418cfe6ee50f84f5c53a87296fb5d7eaaa8ce1a6c3016b
MD5 3a8f6e144e725d67603cebba02685b26
BLAKE2b-256 d527900eb03bbb3871e7e1245d044ce35eb3bb460b78af633cba3250216bb8cb

See more details on using hashes here.

File details

Details for the file fluidkit-1.0.5-py3-none-any.whl.

File metadata

  • Download URL: fluidkit-1.0.5-py3-none-any.whl
  • Upload date:
  • Size: 51.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.30

File hashes

Hashes for fluidkit-1.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 9a4e1a1133f8d3f43be2fa4829be9c7155e19dcfe713a4fab5579c69f38607cc
MD5 30801e4774341c9e0aedf3cf0d90cc2f
BLAKE2b-256 bf19770c2d106e9907cd9dde5502c4682eb51cc0b9897f7639c0caf134c68c60

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page