π¬ Explore Upcoming Features! Remote Functions are an experimental feature in SvelteKit, offering a type-safe alternative to tRPC for full-stack development.
An interactive demonstration of SvelteKit Remote Functions patterns, showcasing type-safe client-server communication with live examples. Experience the future of SvelteKit with end-to-end type safety, automatic serialization, and built-in query batchingβno separate API layer required.
Remote Functions are SvelteKit's approach to type-safe client-server communication. They can be called anywhere in your app but always run on the server, making them perfect for:
- π Safely accessing server-only resources (environment variables, databases)
- π¨ Writing full-stack features in a single file
- π Automatic data fetching and caching
- π Progressive form enhancement
- β‘ Built-in optimizations (batching, lazy discovery)
This demo showcases 9 different patterns for working with Remote Functions:
- Top-level await - Using
{#await query()}
directly in templates - Direct .current access - Accessing
query().current
for manual control - Derived reactive queries - Using
$derived()
for reactive data - Manual refresh - Calling
.refresh()
on demand
- Command pattern - Using
command()
for mutations and updates
- Form pattern - Progressive enhancement with
form()
- Error boundary - Using
<svelte:boundary>
to catch errors - Dynamic import with await - Lazy-loading components that use async data
- Dynamic import (no # syntax) - Testing
{await}
without hash symbol
# Clone the repository
git clone https://github.com/wiesson/svelte-async-remote-fn.git
cd svelte-async-remote-fn
# Install dependencies
pnpm install
# Start development server
pnpm dev
Visit http://localhost:5173 to explore the patterns.
// src/routes/example.remote.ts
import { query } from '$app/server';
import { z } from 'zod';
export const getUser = query(z.object({ id: z.string() }), async ({ id }) => {
return await db.user.findById(id);
});
<!-- src/routes/example/+page.svelte -->
<script>
import { getUser } from '../example.remote';
let userQuery = getUser({ id: '123' });
</script>
{#if userQuery.loading}
<p>Loading...</p>
{:else if userQuery.error}
<p>Error: {userQuery.error.message}</p>
{:else if userQuery.current}
<p>User: {userQuery.current.name}</p>
{/if}
// For mutations and updates
export const updateUser = command(
z.object({ id: z.string(), name: z.string() }),
async ({ id, name }) => {
return await db.user.update(id, { name });
}
);
// Progressive enhancement
export const contactForm = form(
z.object({
email: z.string().email(),
message: z.string().min(10)
}),
async (data) => {
await sendEmail(data);
return { success: true };
}
);
- SvelteKit 5 - The fastest way to build Svelte apps
- Tailwind CSS 4 - Utility-first CSS framework
- shadcn-svelte - Beautiful UI components
- Lucide Icons - Beautiful & consistent icons
- Zod - TypeScript-first schema validation
- π Official Remote Functions Documentation
- π¬ SvelteKit Discussion #13897
- π° What's New in Svelte: August 2025
- β All major patterns covered with live examples
- β Type-safe end-to-end with TypeScript
- β Responsive design with Tailwind CSS
- β Beautiful UI using shadcn-svelte components
- β Toast notifications for user feedback
- β Error handling demonstrations
- β Progressive enhancement examples
Contributions are welcome! If you have ideas for additional patterns or improvements:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-pattern
) - Commit your changes (
git commit -m 'Add amazing pattern'
) - Push to the branch (
git push origin feature/amazing-pattern
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- SvelteKit team for creating Remote Functions
- shadcn for the amazing component library
- The Svelte community for continuous inspiration
Made with β€οΈ using SvelteKit