Getting Started
FluidKit bridges Python and SvelteKit into a unified fullstack framework. Write backend functions in Python — FluidKit registers them as FastAPI endpoints and generates SvelteKit remote functions with full type safety.
Installation
No system Node.js required — FluidKit bundles it automatically.
pip install fluidkitCreate a project
fluidkit init my-app
cd my-appThis scaffolds a SvelteKit project with FluidKit wired in and a working demo app:
my-app/
├── src/
│ ├── routes/
│ │ ├── +layout.svelte
│ │ └── +page.svelte
│ ├── lib/
│ │ ├── demo.py # your backend logic
│ │ └── demo.remote.ts # generated — don't edit
│ └── app.py # FastAPI entry point
├── fluidkit.config.json
├── svelte.config.js
└── package.jsonRun it
fluidkit devThis starts both the FastAPI backend and Vite dev server together with hot module reloading. Open the app and you'll see a working posts demo — try adding posts and liking them.
How the demo works
The scaffolded demo.py contains three decorated functions:
from fluidkit import query, command, form
db = {
"posts": [
{"id": 1, "title": "Hello World", "content": "First post.", "likes": 10},
]
}
@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
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()The route imports and uses them directly:
<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}Notice the import path: $lib/demo.remote. FluidKit generates demo.remote.ts next to your demo.py — this is a standard SvelteKit
remote function file that proxies calls to your Python backend. You never need to edit it.
What just happened?
When you decorated functions with @query, @command, and @form, FluidKit:
- Registered each function as a FastAPI endpoint — with parameter types, validation, and return types extracted automatically
- Generated a
.remote.tsfile — a SvelteKit remote function wrapper that calls your FastAPI endpoint with full type safety - Wired up cache invalidation —
get_posts().refresh()insidelike_postandadd_posttells SvelteKit to refetch that query in the same round-trip
Next steps
- @query — arguments, batching, refresh
- @command — writing data, updating queries, optimistic updates
- @form — fields, validation, file uploads, progressive enhancement
- @prerender — build-time data with optional runtime fallback
- CLI — all available commands
- Configuration — fluidkit.config.json reference