SvelteKit is the full-stack Svelte framework — SSR, form actions, API routes, and more. Tunnel it to test OAuth, webhooks, and share your work without deploying.
Quick Start
npm install -g mekong-cli
mekong auth YOUR_TOKEN# Terminal 1
npm run dev # SvelteKit starts on http://localhost:5173
# Terminal 2
mekong 5173
# → https://happy-tiger-a1b2c3d4.mekongtunnel.devOr together:
npx concurrently "vite dev" "mekong 5173"package.json Scripts
{
"scripts": {
"dev": "vite dev",
"tunnel": "mekong 5173",
"dev:share": "concurrently \"vite dev\" \"mekong 5173\""
}
}Custom Port
// vite.config.ts
import { sveltekit } from '@sveltejs/kit/vite'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [sveltekit()],
server: { port: 4000 },
})mekong 4000Auto-Tunnel Vite Plugin
// vite.config.ts
import { sveltekit } from '@sveltejs/kit/vite'
import { defineConfig } from 'vite'
import { createTunnel } from 'mekong-cli'
export default defineConfig({
plugins: [
sveltekit(),
{
name: 'mekong-tunnel',
configureServer(server) {
server.httpServer?.once('listening', async () => {
const port = (server.httpServer?.address() as any)?.port ?? 5173
const tunnel = await createTunnel({ port })
setTimeout(() => {
console.log(`\n ➜ Tunnel: \x1b[36m${tunnel.url}\x1b[0m\n`)
}, 100)
})
},
},
],
})Environment Variables
# .env
PUBLIC_APP_URL=https://happy-tiger-a1b2c3d4.mekongtunnel.dev
PRIVATE_STRIPE_SECRET=sk_test_...// In Svelte components (public vars)
import { PUBLIC_APP_URL } from '$env/static/public'
// In server files (private vars)
import { PRIVATE_STRIPE_SECRET } from '$env/static/private'Form Actions Via Tunnel
SvelteKit form actions work seamlessly through the tunnel:
<!-- src/routes/contact/+page.svelte -->
<script lang="ts">
import type { ActionData } from './$types'
export let form: ActionData
</script>
<form method="POST">
<input name="email" type="email" required />
<button type="submit">Subscribe</button>
{#if form?.success}
<p>Thank you!</p>
{/if}
</form>// src/routes/contact/+page.server.ts
import type { Actions } from './$types'
export const actions: Actions = {
default: async ({ request }) => {
const data = await request.formData()
const email = data.get('email')
// process...
return { success: true }
},
}API Routes (Endpoints)
// src/routes/api/webhook/+server.ts
import type { RequestHandler } from './$types'
export const POST: RequestHandler = async ({ request }) => {
const body = await request.json()
console.log('Webhook:', body)
return new Response(JSON.stringify({ ok: true }), {
headers: { 'Content-Type': 'application/json' },
})
}mekong 5173
# POST https://your-tunnel.mekongtunnel.dev/api/webhookOAuth with SvelteKit
Using @auth/sveltekit:
AUTH_SECRET=your-secret
GITHUB_ID=...
GITHUB_SECRET=...
AUTH_URL=https://happy-tiger-a1b2c3d4.mekongtunnel.dev// src/auth.ts
import { SvelteKitAuth } from '@auth/sveltekit'
import GitHub from '@auth/sveltekit/providers/github'
export const { handle, signIn, signOut } = SvelteKitAuth({
providers: [GitHub],
})Add to your GitHub OAuth app:
https://happy-tiger-a1b2c3d4.mekongtunnel.dev/auth/callback/githubCORS for API Routes
// src/hooks.server.ts
import type { Handle } from '@sveltejs/kit'
export const handle: Handle = async ({ event, resolve }) => {
const response = await resolve(event)
response.headers.set('Access-Control-Allow-Origin', '*')
return response
}Tips
- SvelteKit's live reload and HMR work locally; the tunnel shows the rendered output
+page.server.tsand+server.tsfiles run server-side — all requests hit your local machine- WebSocket support (
+server.tswith upgrade handler) works through the MekongTunnel proxy