Integrations

Svelte

Explain the minimal setup, provider registration, and Svelte-specific patterns in @ginjou/svelte.

@ginjou/svelte is the base Svelte adapter for Ginjou.

It exposes Ginjou's core contracts through Svelte's setContext/getContext, adds TanStack Query-backed data hooks, and includes the controller layer for resource-oriented pages.

The package targets Svelte 5 and uses runes throughout.

Installation

Install @ginjou/svelte together with @tanstack/svelte-query.

Ginjou uses TanStack Query for query and mutation state in Svelte, so both packages are part of the base setup.

pnpm add @ginjou/svelte @tanstack/svelte-query

Setup

The smallest useful Svelte setup starts with two contexts:

  1. defineQueryClientContext() for TanStack Query state.
  2. defineFetchersContext() for data access.

Register them once near the app root so every Ginjou composable reads the same shared contexts.

<script lang="ts">
import { defineFetcher } from '@ginjou/core'
import { defineFetchersContext, defineQueryClientContext } from '@ginjou/svelte'

const { children } = $props()

defineQueryClientContext({
    defaultOptions: {
        queries: {
            staleTime: 5 * 60 * 1000,
        },
    },
})

defineFetchersContext({
    default: defineFetcher({
        async getList() {
            return {
                data: [],
                total: 0,
            }
        },
        async getOne({ id }) {
            return {
                data: { id },
            }
        },
    }),
})
</script>

{@render children()}

From there, add router, auth, authz, notifications, i18n, realtime, and resources only when the app needs them.

Contexts

@ginjou/svelte keeps all shared contexts explicit through Svelte's setContext/getContext.

Each defineXContext() call registers one app-level implementation of a Ginjou contract. Composables, controllers, and lower-level helpers read from those contexts later.

ProviderWhen to add itGuide
defineQueryClientContextAlways for the data layerData
defineFetchersContextAlways for the data layerData
defineAuthContextWhen the app supports login, logout, or identityAuthentication
defineAuthzContextWhen the app checks permissions or access rulesAuthorization
defineRouterContextWhen navigation, current location, or controller route sync matterRouter
defineI18nContextWhen the app translates text or switches localeI18n
defineNotificationContextWhen the app shows toast-like feedbackNotifications
defineRealtimeContextWhen queries subscribe or mutations publish realtime eventsRealtime
defineResourceContextWhen the app defines shared resource metadataResources

Most Svelte apps start with query client and fetchers, then add the other contexts only when they become necessary.

This page only covers the integration shape. Use the linked guides for the full contract and behavior of each context.

Runes

@ginjou/svelte is built for Svelte 5 and uses runes throughout.

Query and mutation results from @tanstack/svelte-query are reactive by default through Svelte 5 signals. Accessing .data, .isLoading, .isPending, and other result fields in reactive contexts such as $derived or templates works without any extra wrapping.

Controller state fields like currentPage, perPage, filters, sorters, and search are exposed as plain reactive properties that can be read and assigned directly.

posts.svelte
<script lang="ts">
import { useList } from '@ginjou/svelte'

const listPage = useList({
    resource: 'posts',
})

function nextPage() {
    listPage.currentPage += 1
}
</script>

MaybeAccessor<T> means the prop accepts either a plain value (T) or an accessor function (() => T). Use the function form when the prop value depends on reactive state.

post.svelte
<script lang="ts">
import { useGetOne } from '@ginjou/svelte'

const { id } = $props()

const postQuery = useGetOne(() => ({
    resource: 'posts',
    id,
}))
</script>

Ecosystem

These packages extend @ginjou/svelte with third-party library integrations.

svelte-spa-router

@ginjou/with-svelte-spa-router connects svelte-spa-router to Ginjou's router contract.
Copyright © 2026