prodigist1k downloadsTransform your vault into a reactive computational environment. Create dynamic React components directly in your notes.
Transform your Obsidian vault into a reactive computational environment. ReactiveNotes seamlessly integrates React's component ecosystem with Obsidian's powerful note-taking capabilities, enabling dynamic, interactive documents that evolve with your thoughts.
⚠️ Mobile Support: Currently optimized for desktop use. Mobile support is under development.
New to ReactiveNotes? Start here!
🎨 See it in Action! (Examples): Explore a gallery of what you can build.
For manual installation:
.obsidian/plugins folderCreate a React component in any note:
```react
const Greeting = () => {
const [name, setName] = useState("World");
return <h1>Hello, {name}!</h1>;
};
export default Greeting;
```
Component Requirements:
Build dynamic UIs directly in your notes with React 18 and TypeScript. Features robust error handling, lifecycle management, and real-time updates.
Effortlessly manage component state with multiple options:
useStorage hook to save and load component data directly within your note's frontmatter. State travels with your note!useStorage to interact with the frontmatter of other notes in your vault.react_data section, for broader compatibility.useState and other React hooks for local, non-persistent component state.localStorage: Access global, non-note-specific storage for preferences or shared data across all notes.The plugin provides a flexible file reading utility through the readFile function that helps you interactively select and read files from your vault.
const fileData = await readFile( path,extensions);
path (optional): Direct path to a specific file. If provided, skips the file selector. Default: nullextensions (optional): Array of file extensions to filter by. Default: ['txt', 'md', 'json', 'csv']This utility is particularly useful for components that need to process files from your vault, such as data visualizations, document analysis, and custom importers.
➡️ Read Files Usage and Examples
Import additional libraries from cdnjs:
import Chart from 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.0/chart.umd.min.js';
Requirements:
const theme = getTheme(); // Returns 'dark' or 'light' correspodning to obsidian theme
const styles = {
background: theme === 'dark' ? 'var(--background-primary)' : 'white',
color: theme === 'dark' ? 'var(--text-normal)' : 'black'
};
// Or use 'dark:' within your components
Import React code from other notes in your vault:
// Import code from another note
vaultImport('Components/SharedComponents.md', 0); // 0 = first code block
vaultImport('Hooks/CustomHooks.md', 1); // 1 = second code block
const MyComponent = () => {
// Use imported components and hooks from these files
const data = useImportedHook();
return <ImportedComponent data={data} />;
};
Not all react code blocks need to be valid React you can use React code blocks to store and organize utility functions, hooks, and other definitions:
// This displays as a definition storage block instead of rendering
const utilities = () => ({
formatDate: (date) => date.toLocaleDateString(),
calculateSum: (arr) => arr.reduce((a, b) => a + b, 0),
parseData: (raw) => JSON.parse(raw)
});
export default utilities;
When a code block returns an object instead of JSX, it automatically displays as a storage block showing all exported definitions. If you have multiple objects containing definitions only the first object will be previewed.
Perfect for:
Utility function collections Custom hook libraries Configuration objects Shared constants
Import these definitions into other components using vaultImport().
ReactiveNotes provides access to popular libraries and components directly in your notes:
// React and hooks
import React, { useState, useEffect, useRef, useMemo } from 'react';
// Data visualization
import { LineChart, BarChart, PieChart } from 'recharts';
import { createChart } from 'lightweight-charts';
// Data processing
import Papa from 'papaparse'; // CSV parsing
import * as XLSX from 'xlsx'; // Excel files
import * as mathjs from 'mathjs'; // Mathematics
import { format, parseISO } from 'date-fns'; // Date handling
// Interface components
import { Card, Tabs, Switch } from '@/components/ui';
import { TrendingUp, Activity, Settings } from 'lucide-react'; // 70+ icons
import * as LucideIcons from 'lucide-react'; // For complete access just use LucideIcons.IconName
Checkout the full component reference for a complete list of available libraries, components and utilities.
If needed, libraries not provided within this list can be imported via CDN imports.
// Note context
noteContext.frontmatter // All frontmatter properties (not just react_data)
noteContext.path // Full path to current note
noteContext.basename // Note filename without extension
// Utilities
getTheme() // Returns 'dark' or 'light'
readFile(path, exts) // File reading utility
// Update frontmatter properties, either in react_data (extProp:false) or at root level(extProp:true) Defaults to react_data
updateFrontmatter(key, value, notePath?, extProp?)
// If properties are null returns entire frontmatter or current note if path not provided, extProp defaults to true: entire frontmatter
getFrontmatter(key?,defaultValue?,notePath?, extProp?)
vaultImport(path, index) // Preprocessor directive to include code from other notes (not a runtime function)
Notice(message, timeout?) // Display non-blocking notifications (use instead of alert() which blocks the UI thread)
```react
const DataChart = () => {
const data = [
{ month: 'Jan', value: 100 },
{ month: 'Feb', value: 150 },
{ month: 'Mar', value: 120 }
];
return (
<ResponsiveContainer width="100%" height={300}>
<LineChart data={data}>
<XAxis dataKey="month" />
<YAxis />
<Line type="monotone" dataKey="value" />
<Tooltip />
</LineChart>
</ResponsiveContainer>
);
};
```

const DrawingCanvas = () => {
const canvasRef = useRef(null);
useEffect(() => {
const ctx = canvasRef.current.getContext('2d');
ctx.fillStyle = getTheme() === 'dark' ? '#fff' : '#000';
// Your drawing code
return () => {
// Cleanup
};
}, []);
return <canvas ref={canvasRef} className="w-full h-64" />;
};
```react
const NoteTracker = () => {
const [notes, setNotes] = useStorage('notes', []);
const addNote = (text) => {
setNotes(prev => [...prev, {
id: Date.now(),
text,
created: new Date()
}]);
};
return (
<Card>
<CardHeader>
<CardTitle>My Notes</CardTitle>
</CardHeader>
<CardContent>
{notes.map(note => (
<div key={note.id}>{note.text}</div>
))}
<Button onClick={() => addNote("New Note")}>
Add Note
</Button>
</CardContent>
</Card>
);
};
```
```react
const NetworkGraph = () => {
const [nodes] = useState([
{ id: 1, label: 'Node 1' },
{ id: 2, label: 'Node 2' }
]);
const [links] = useState([
{ source: 1, target: 2 }
]);
return (
<ForceGraph
graphData={{ nodes, links }}
nodeAutoColorBy="label"
nodeLabel="label"
/>
);
};
```

Simulator (Use within reason for performance)

File Upload

3D Animation

Tabbed UI

Progression Dashboard
Knowledge progression dashboard using persistant storage and ability to make new notes/categories

Integrated use case with MCP
MCP fetches data from youtube and uses Reactive Notes to display react component for visualising fetched data.

Games utilising event listeners for key action mapping

Component not rendering
CDN imports not working
State persistence issues
Performance Problems
Environment Constraints
Performance Considerations
Work in Progress
Preset Component Templates: Kickstart your development with a library of ready-to-use component templates for common use cases.
AI-Powered Component Generation: Leverage AI (e.g., via MCP integration) to assist in generating boilerplate or even complete React components based on your descriptions.
GUI for Component Snippets: An intuitive graphical user interface to easily save your favorite or frequently used component code snippets and load them into your notes.
Mobile-Specific Components & UI: Introducing components and UI patterns specifically designed for the mobile experience.
We welcome contributions! Here's how to get started:
Please read our Contributing Guide for details.
MIT License - see LICENSE for details
⚡️Built to advance the Obsidian powerhouse