Documentation Index
Fetch the complete documentation index at: https://mintlify.com/amark/gun/llms.txt
Use this file to discover all available pages before exploring further.
React Integration
GUN integrates seamlessly with React applications, enabling real-time, decentralized data synchronization in your React components.
Installation
Install GUN
Install GUN via npm or yarn:npm install gun
# or
yarn add gun
Import GUN in your React app
Import GUN in your component or at the application level:import Gun from 'gun/gun'
Initialize GUN instance
Create a GUN instance, typically in your main App component:const gun = Gun(location.origin + '/gun')
// Or for local-only development:
const gun = Gun()
Basic Usage
Setting Up GUN in App Component
Here’s how to initialize GUN in your main App component and pass it to child components:
import React, { Component } from 'react'
import Gun from 'gun/gun'
import Todos from './Todos'
class App extends Component {
constructor() {
super();
this.gun = Gun(location.origin + '/gun')
}
render() {
return (
<div>
<h1>My GUN App</h1>
<Todos gun={this.gun} />
</div>
);
}
}
export default App;
Using GUN in a Todo Component
Here’s a complete example of a Todo component using GUN for real-time data synchronization:
import React, { Component } from 'react'
import Gun from 'gun/gun'
import 'gun/lib/path'
const formatTodos = todos => Object.keys(todos)
.map(key => ({ key, val: todos[key] }))
.filter(t => Boolean(t.val) && t.key !== '_')
export default class Todos extends Component {
constructor({gun}) {
super()
this.gun = gun.get('todos');
this.state = {newTodo: '', todos: []}
}
componentWillMount() {
this.gun.on(todos => this.setState({
todos: formatTodos(todos)
}))
}
add = e => {
e.preventDefault()
this.gun.path(Gun.text.random()).put(this.state.newTodo)
this.setState({newTodo: ''})
}
del = key => this.gun.path(key).put(null)
handleChange = e => this.setState({ newTodo: e.target.value})
render() {
return <div>
<form onSubmit={this.add}>
<input value={this.state.newTodo} onChange={this.handleChange} />
<button onClick={this.add}>Add</button>
</form>
<ul>
{this.state.todos.map(todo =>
<li key={todo.key} onClick={_=>this.del(todo.key)}>
{todo.val}
</li>
)}
</ul>
</div>
}
}
Real-time Chat Component
Here’s an example of a real-time chat component using GUN:
import React, { Component } from 'react'
import Gun from 'gun/gun'
const formatMsgs = msgs => Object.keys(msgs)
.map(key => ({ key, ...msgs[key] }))
.filter(m => Boolean(m.when) && m.key !== '_')
.sort((a, b) => a.when - b.when)
.map(m => ((m.whenFmt = new Date(m.when).toLocaleString().toLowerCase()), m))
export default class Chat extends Component {
constructor({gun}) {
super()
this.gun = gun.get('chat');
this.state = {
newMsg: '',
name: (document.cookie.match(/alias\=(.*?)(\&|$|\;)/i)||[])[1]||'',
msgs: {},
}
}
componentWillMount() {
const tmpState = {}
this.gun.map().val((msg, key) => {
tmpState[key] = msg
this.setState({msgs: Object.assign({}, this.state.msgs, tmpState)})
})
}
send = e => {
e.preventDefault()
const who = this.state.name || 'user' + Gun.text.random(6)
this.setState({name: who})
document.cookie = ('alias=' + who)
const when = Gun.time.is()
const key = `${when}_${Gun.text.random(4)}`
this.gun.path(key).put({
who,
when,
what: this.state.newMsg,
})
this.setState({newMsg: ''})
}
render() {
const msgs = formatMsgs(this.state.msgs)
return <div>
<ul>
{msgs.map(msg =>
<li key={msg.key}>
<b>{msg.who}:</b> {msg.what}
<span className="when">{msg.whenFmt}</span>
</li>
)}
</ul>
<form onSubmit={this.send}>
<input
value={this.state.name}
className="who"
onChange={e => this.setState({ name: e.target.value})}
/>
<input
value={this.state.newMsg}
className="what"
onChange={e => this.setState({ newMsg: e.target.value})}
/>
<button onClick={this.send}>Send</button>
</form>
</div>
}
}
React Hooks Pattern
For functional components, you can create custom hooks for GUN:
import { useState, useEffect } from 'react'
function useGunState(gun, initialState) {
const [state, setState] = useState(initialState)
useEffect(() => {
gun.on(data => setState(data))
}, [])
return [state, (newData) => gun.put(newData)]
}
// Usage
function MyComponent({ gun }) {
const [todos, setTodos] = useGunState(gun.get('todos'), [])
return (
<div>
{/* Your component JSX */}
</div>
)
}
State Management
GUN can work alongside or replace traditional state management solutions like Redux:
- Real-time updates: GUN’s
.on() method provides automatic state synchronization
- Offline-first: Data persists locally and syncs when connected
- Decentralized: No central server required for data synchronization
Best Practices
- Initialize once: Create your GUN instance at the app level and pass it down via props or context
- Clean up subscriptions: Use
componentWillUnmount() to remove listeners when components unmount
- Filter metadata: GUN stores metadata with
_ keys - filter these out when rendering
- Use keys wisely: Use
Gun.text.random() for unique keys or timestamps for ordered data
Common Patterns
Passing GUN via Context
import React, { createContext, useContext } from 'react'
import Gun from 'gun/gun'
const GunContext = createContext()
export function GunProvider({ children }) {
const gun = Gun(location.origin + '/gun')
return <GunContext.Provider value={gun}>{children}</GunContext.Provider>
}
export function useGun() {
return useContext(GunContext)
}
Next Steps