Convex SolidJS Client
npm install convex-solidjs



> Type-safe, reactive Convex client for SolidJS with real-time subscriptions and fine-grained reactivity.
Convex is the typesafe backend-as-a-service with realtime updates, server functions, crons and scheduled jobs, file storage, vector search, and more.
convex-solidjs provides a native SolidJS integration with automatic reactivity, type safety, and real-time updates.
``bash`
npm install convex convex-solidjsor
pnpm add convex convex-solidjs
Run npx convex init to get started with Convex.
- šÆ Zero any types - Fully type-safe with excellent TypeScript support
- ā” SolidJS Native - Built with SolidJS primitives (createResource, createSignal, createMemo)
- š Reactive Arguments - Pass signals or static values, the choice is yours
- š Real-time Updates - Automatic subscription to Convex queries with live data synchronization
- š¦ Small Bundle - Minimal overhead on top of Convex client (~5KB gzipped)
- šØ Clean API - Intuitive and easy to use
- šŖ SSR Support - Server-side rendering ready with initialData option
- š Stale-While-Revalidate - Keep showing previous data while loading new results
`bash`
npm install convex convex-solidjsor
pnpm add convex convex-solidjs
`bash`
npx convex init
Wrap your app with ConvexProvider:
`tsx
import { setupConvex, ConvexProvider } from 'convex-solidjs'
import { render } from 'solid-js/web'
import App from './App'
const client = setupConvex(import.meta.env.VITE_CONVEX_URL)
render(
() => (
),
document.getElementById('root')!
)
`
Queries automatically re-run when their arguments change:
`tsx
import { useQuery } from 'convex-solidjs'
import { api } from '../convex/_generated/api'
import { createSignal, For, Show } from 'solid-js'
function Messages() {
const [channel, setChannel] = createSignal('general')
// Query re-runs automatically when channel changes
const messages = useQuery(
api.messages.list,
() => ({ channel: channel() }), // Reactive arguments!
{ keepPreviousData: true } // Show old data while loading new
)
return (
{message.text}}
Updating...
$3
Use
useMutation() for type-safe mutations with loading states:`tsx
import { useMutation } from 'convex-solidjs'
import { api } from '../convex/_generated/api'function MessageForm() {
const [text, setText] = createSignal('')
const sendMessage = useMutation(api.messages.send)
const handleSubmit = async (e: Event) => {
e.preventDefault()
try {
await sendMessage.mutate({
text: text(),
channel: 'general',
})
setText('')
} catch (error) {
console.error('Failed to send:', error)
}
}
return (
)
}
`$3
Use
useAction() for Convex actions (same API as mutations):`tsx
const generateResponse = useAction(api.ai.generate)const handleGenerate = async () => {
const response = await generateResponse.mutate({
prompt: 'Hello, AI!',
})
console.log(response)
}
`API Reference
$3
Creates a Convex client instance.
`tsx
const client = setupConvex('https://your-app.convex.cloud', {
// Optional: disable in SSR
disabled: isServer,
})
`$3
Subscribe to a Convex query with reactive arguments.
`tsx
const query = useQuery(
api.messages.list,
() => ({ channel: currentChannel() }), // Can be a function or static value
{
enabled: isLoggedIn(), // Conditional fetching
keepPreviousData: true, // Show stale data while loading
initialData: [], // SSR/Hydration support
},
)// Returns:
query.data() // T | undefined
query.error() // Error | undefined
query.isLoading() // boolean
query.isStale() // boolean
query.refetch() // () => void
`$3
Execute Convex mutations with loading states.
`tsx
const mutation = useMutation(api.messages.send)// Call it
await mutation.mutate({ text: 'Hello' })
// or
await mutation.mutateAsync({ text: 'Hello' })
// State
mutation.data() // Result of last successful mutation
mutation.error() // Error from last failed mutation
mutation.isLoading() // Is mutation in progress
mutation.reset() // Clear data and error
`$3
Execute Convex actions (same API as mutations).
`tsx
const action = useAction(api.ai.generate)
await action.mutate({ prompt: '...' })
`$3
Get the raw Convex client for advanced use cases:
`tsx
const client = useConvexClient()// Set auth
await client.setAuth(token)
// Call functions directly
const result = await client.mutation(api.foo.bar, args)
`Key Design Decisions
1. Reactive Arguments: Both args and options can be static values or accessor functions
2. Resource-Based: Uses SolidJS's
createResource for optimal performance
3. Type Safety: Full TypeScript inference with zero type assertions
4. Clean Returns: No property getters, just simple accessor functionsAdvanced Usage
$3
Control when queries run with the
enabled option:`tsx
const user = useQuery(
api.users.current,
{},
() => ({ enabled: isAuthenticated() }) // Only fetch when authenticated
)
`$3
Support server-side rendering with initial data:
`tsx
const messages = useQuery(
api.messages.list,
{ channel: 'general' },
{
initialData: serverData, // Data from SSR
keepPreviousData: true
}
)
`$3
Access the Convex client directly for advanced scenarios:
`tsx
import { useConvexClient } from 'convex-solidjs'function AuthButton() {
const client = useConvexClient()
const handleLogin = async () => {
await client.setAuth(token)
}
return
}
`Differences from Other Frameworks
$3
- No hooks rules: Use anywhere in SolidJS components
- Fine-grained reactivity: Only re-runs what changes
- Accessor pattern: Returns functions, not values
- Reactive arguments: Pass signals directly for automatic updates$3
- Signal-based state: Uses SolidJS signals instead of Svelte's runes
- Resource integration: Built on createResource for optimal async handling
- Batch updates: Leverages SolidJS's batching for performanceExample Application
Check out the
/dev folder for a complete chat application showcasing:
- User and channel creation
- Real-time message updates
- AI response generation with GPT-4
- Optimistic updates
- Error handling
- Loading statesRun the demo:
`bash
cd dev
pnpm install
pnpm run dev
`Deploying
In production build pipelines use the build command:
`bash
npx convex deploy --cmd-url-env-var-name VITE_CONVEX_URL --cmd 'npm run build'
`to build your SolidJS app and deploy Convex functions.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
$3
1. Clone the repository
2. Install dependencies:
pnpm install
3. Build the library: pnpm run build
4. Run tests: pnpm test (if applicable)
5. Run the demo: cd dev && pnpm run dev$3
`
convex-solidjs/
āāā src/
ā āāā index.tsx # Main library code
āāā dev/ # Demo application
ā āāā convex/ # Convex backend
ā āāā App.tsx # Demo UI
āāā package.json
āāā README.md
``- Documentation
- Discord Community
- GitHub Issues
MIT Ā© Frank
---
Built with ā¤ļø for the SolidJS and Convex communities