Svelte Integration
Mearie provides Svelte stores that work seamlessly with Svelte's fine-grained reactivity and runes for full type safety.
Installation
Install the core package and the Svelte integration:
npm install mearie @mearie/svelteyarn add mearie @mearie/sveltepnpm add mearie @mearie/sveltebun add mearie @mearie/sveltedeno add npm:mearie npm:@mearie/svelteSetup
1. Add Build Plugin
Add Mearie's build plugin to enable automatic type generation from your GraphQL documents:
// vite.config.ts
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import mearie from 'mearie/vite';
export default defineConfig({
plugins: [svelte(), mearie()],
});TIP
By default, Mearie looks for ./schema.graphql relative to your vite.config.ts. For custom schema locations or advanced configuration, see Codegen Config.
2. Create Client
Create a GraphQL client with your API endpoint. Links are middleware-style handlers that process requests and responses. At least one terminating link is required (in this case, httpLink). See Links for more details.
// src/lib/graphql-client.ts
import { createClient, httpLink, cacheLink, dedupLink } from 'mearie';
export const client = createClient({
links: [
dedupLink(),
cacheLink(),
httpLink({
url: 'https://api.example.com/graphql',
}),
],
});3. Set Up Provider
Wrap your app with the client provider to make the GraphQL client available throughout your component tree:
<!-- src/main.svelte -->
<script lang="ts">
import { setClient } from '@mearie/svelte';
import { client } from './lib/graphql-client';
setClient(client);
</script>Stores
createQuery
Fetch data with automatic caching:
<script lang="ts">
import { graphql } from 'mearie'
import { createQuery } from '@mearie/svelte'
interface Props {
userId: string;
}
let { userId }: Props = $props()
const query = createQuery(
graphql(`
query GetUserQuery($id: ID!) {
user(id: $id) {
id
name
email
avatar
bio
age
}
}
`),
() => ({ id: userId })
)
</script>
{#if query.loading}
<div>Loading...</div>
{:else if query.error}
<div>Error: {query.error.message}</div>
{:else}
<div>
<img src={query.data.user.avatar} alt={query.data.user.name} />
<h1>{query.data.user.name}</h1>
{#if query.data.user.bio}
<p>{query.data.user.bio}</p>
{/if}
<p>Email: {query.data.user.email}</p>
<p>Age: {query.data.user.age}</p>
<button onclick={() => query.refetch()}>Refresh</button>
</div>
{/if}createMutation
Modify data with automatic cache updates:
<script lang="ts">
import { graphql } from 'mearie'
import { createMutation } from '@mearie/svelte'
interface Props {
userId: string;
}
let { userId }: Props = $props()
let name = $state('')
const mutation = createMutation(
graphql(`
mutation UpdateUserMutation($id: ID!, $name: String!) {
updateUser(id: $id, input: { name: $name }) {
id
name
}
}
`)
)
const handleSubmit = async (e: SubmitEvent) => {
e.preventDefault()
await mutation.mutate({ id: userId, name })
}
</script>
<form onsubmit={handleSubmit}>
<input bind:value={name} required />
<button type="submit" disabled={mutation.loading}>
{mutation.loading ? 'Saving...' : 'Save'}
</button>
</form>createFragment
Co-locate data requirements with components:
<script lang="ts">
import { graphql } from 'mearie'
import { createFragment } from '@mearie/svelte'
import type { UserCard_user$key } from 'mearie/types'
interface Props {
user: UserCard_user$key;
}
let { user }: Props = $props()
const data = createFragment(
graphql(`
fragment UserCard_user on User {
id
name
avatar
email
}
`),
() => user,
)
</script>
<div class="card">
<img src={data().avatar} alt={data().name} />
<h3>{data().name}</h3>
<p>{data().email}</p>
</div>createSubscription
Real-time updates via subscriptions:
<script lang="ts">
import { graphql } from 'mearie'
import { createSubscription } from '@mearie/svelte'
interface Props {
chatId: string;
}
let { chatId }: Props = $props()
const subscription = createSubscription(
graphql(`
subscription MessageAddedSubscription($chatId: ID!) {
messageAdded(chatId: $chatId) {
id
body
author {
name
}
}
}
`),
() => ({ chatId })
)
</script>
<div>
<div>{subscription.loading ? 'Connecting...' : 'Connected'}</div>
{#if subscription.data?.messageAdded}
<div>
<strong>{subscription.data.messageAdded.author.name}:</strong>
{subscription.data.messageAdded.body}
</div>
{/if}
</div>Fine-Grained Reactivity
Svelte's fine-grained reactivity with runes works seamlessly with Mearie:
<script lang="ts">
import { graphql } from 'mearie';
import { createQuery } from '@mearie/svelte';
let userId = $state('123');
// Automatically refetches when userId changes
const query = createQuery(
graphql(`
query GetUserQuery($id: ID!) {
user(id: $id) {
id
name
email
}
}
`),
() => ({ id: userId })
);
</script>
{#if query.data}
<div>
<h1>{query.data.user.name}</h1>
<p>{query.data.user.email}</p>
</div>
{/if}
<button onclick={() => userId = '456'}>
Change User
</button>Next Steps
- Queries - Learn more about queries
- Mutations - Learn more about mutations
- Fragments - Learn more about fragments
- Subscriptions - Learn more about subscriptions