Solid Integration
Mearie provides Solid primitives that leverage fine-grained reactivity for optimal performance and full type safety.
Installation
Install the core package and the Solid integration:
npm install mearie @mearie/solid
yarn add mearie @mearie/solid
pnpm add mearie @mearie/solid
bun add mearie @mearie/solid
deno add npm:mearie npm:@mearie/solid
Setup
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 solid from 'vite-plugin-solid';
import mearie from 'mearie/vite';
export default defineConfig({
plugins: [solid(), 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/index.tsx
import { ClientProvider } from '@mearie/solid';
import { client } from './lib/graphql-client';
<ClientProvider client={client}>
<App />
</ClientProvider>;
Primitives
createQuery
Fetch data with fine-grained reactivity:
import { type Component } from 'solid-js';
import { graphql } from 'mearie';
import { createQuery } from '@mearie/solid';
interface UserProfileProps {
userId: string;
}
export const UserProfile: Component<UserProfileProps> = (props) => {
const query = createQuery(
graphql(`
query GetUserQuery($id: ID!) {
user(id: $id) {
id
name
email
avatar
bio
age
}
}
`),
() => ({
id: props.userId,
}),
);
if (query.loading) return <div>Loading...</div>;
if (query.error) return <div>Error: {query.error.message}</div>;
return (
<div>
<img src={query.data.user.avatar} alt={query.data.user.name} />
<h1>{query.data.user.name}</h1>
{query.data.user.bio && <p>{query.data.user.bio}</p>}
<p>Email: {query.data.user.email}</p>
<p>Age: {query.data.user.age}</p>
<button onClick={() => query.refetch()}>Refresh</button>
</div>
);
};
createMutation
Modify data with automatic cache updates:
import { type Component, createSignal } from 'solid-js';
import { graphql } from 'mearie';
import { createMutation } from '@mearie/solid';
interface EditUserFormProps {
userId: string;
}
export const EditUserForm: Component<EditUserFormProps> = (props) => {
const [name, setName] = createSignal('');
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: props.userId, name: name() });
};
return (
<form onSubmit={handleSubmit}>
<input value={name()} onInput={(e) => setName(e.currentTarget.value)} required />
<button type="submit" disabled={mutation.loading}>
{mutation.loading ? 'Saving...' : 'Save'}
</button>
</form>
);
};
createFragment
Co-locate data requirements with components:
import { type Component } from 'solid-js';
import { graphql } from 'mearie';
import { createFragment } from '@mearie/solid';
import type { UserCard_user$key } from 'mearie/types';
interface UserCardProps {
user: UserCard_user$key;
}
export const UserCard: Component<UserCardProps> = (props) => {
const data = createFragment(
graphql(`
fragment UserCard_user on User {
id
name
avatar
email
}
`),
() => props.user,
);
return (
<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:
import { type Component } from 'solid-js';
import { graphql } from 'mearie';
import { createSubscription } from '@mearie/solid';
interface ChatMessagesProps {
chatId: string;
}
export const ChatMessages: Component<ChatMessagesProps> = (props) => {
const subscription = createSubscription(
graphql(`
subscription MessageAddedSubscription($chatId: ID!) {
messageAdded(chatId: $chatId) {
id
body
author {
name
}
}
}
`),
() => ({ chatId: props.chatId }),
);
return (
<div>
<div>{subscription.loading ? 'Connecting...' : 'Connected'}</div>
{subscription.data?.messageAdded && (
<div>
<strong>{subscription.data.messageAdded.author.name}:</strong>
{subscription.data.messageAdded.body}
</div>
)}
</div>
);
};
Fine-Grained Reactivity
Solid's fine-grained reactivity works seamlessly with Mearie:
import { type Component } from 'solid-js';
import { graphql } from 'mearie';
import { createQuery } from '@mearie/solid';
interface UserProfileProps {
userId: string;
}
export const UserProfile: Component<UserProfileProps> = (props) => {
const query = createQuery(
graphql(`
query GetUserQuery($id: ID!) {
user(id: $id) {
id
name
email
}
}
`),
() => ({
id: props.userId,
}),
);
return (
<div>
<h1>{query.data.user.name}</h1>
<p>{query.data.user.email}</p>
</div>
);
};
Next Steps
- Queries - Learn more about queries
- Mutations - Learn more about mutations
- Fragments - Learn more about fragments
- Subscriptions - Learn more about subscriptions