Repository files navigation

Homebase React

CICDLicenseTwitter Follow

The React state management library for write-heavy applications

Supported languages, frameworks and DBs:

  • JS + React + Datascript (jump)
  • CLJS + Reagent + Datascript (jump)
  • Datahike support coming soon

What and Why

As data and our need to annotate and organize it grows, so does our need for supporting state in write-heavy applications.

To solve this problem, modern write-heavy applications such as Superhuman, Roam Research, and Facebook Messenger built their own embedded data layers to enable these more sophisticated user experiences.

Homebase-react enables developers to access the same embedded datalog database as Roam Research through React hooks. You no longer have to build out a team or learn specialized tools like Clojure in order to build a delightful write-heavy application.

Testimonials

Homebase is executing on the vision of data usage, portability, and management we had when building Firebase. We never got there. I'm excited!

—James Tamplin, Founder/CEO of Firebase

Datalog is the future of end-user programming, personal productivity software, p2p software, etc.

—Chet Corcos, Founding Engineer of Notion

Javascript + React

Start by installing homebase-react.

NPM VersionBundle Size

# NPM
npm install homebase-react --save
# Yarn
yarn add homebase-react

Optionally install the datalog-consolechrome extension to inspect the homebase-react DB in your browser.

⭐️ 📖 Read the JS docs ⚛️ ⭐️

import{useCallback}from'react'import{HomebaseProvider,useEntity,useTransact}from'homebase-react'constRootComponent=()=>(// Create a DB and set some starting data<HomebaseProviderconfig={{initialData: [{counter: {id: 1,count: 0}}]}}><App/></HomebaseProvider>)constApp=()=>{// Get entity id = 1const[counter]=useEntity(1)const[transact]=useTransact()return(<buttononClick={()=>{// Increment and save the counttransact([{counter: {id: 1,count: counter.get('count')+1}}])}>{/* Render the count */}Increment{counter.get('count')}</button>)}

Live demo

ClojureScript + Reagent

Start by adding homebase-react.

Clojars Project

Optionally add datalog-console and its corresponding chrome extension to inspect the DB in your browser.

Clojars Project

⭐️ 📖 Read the CLJS docs ƛ ⭐️

(nshomebase.dev.example.reagent.counter
(:require
[datascript.core :as d]
[homebase.reagent :as hbr]
[datalog-console.integrations.datascript :as datalog-console]))
(defdb-conn (d/create-conn {}))
(d/transact! db-conn [[:db/add1:count0]]) ; Transact some starting data.
(hbr/connect! db-conn) ; Connect homebase.reagent to the database.
(datalog-console/enable! {:conn db-conn}) ; Also connect the datalog-console extension for better debugging.
(defncounter []
(let [[entity] (hbr/entity db-conn 1)] ; Get a homebase.reagent/Entity. Note the use of db-conn and not @db-conn, this makes it reactive.
(fn []
[:div"Count: " (:count @entity) ; Deref the entity just like a reagent/atom.
[:div
[:button {:on-click #(d/transact! db-conn [[:db/add1:count (inc (:count @entity))]])} ; Use d/transact! just like normal."Increment"]]])))

Live demo

Roadmap

  1. Improve developer tools: custom chrome formatters, DB admin console extension
  2. Rewrite React ↔ Homebase cache
    1. Support async DB access (for Datahike)
    2. Reactive query planning (better perf on pages with lots of live reads)
  3. Swap Datascript out for Datahike
    1. Immutability
    2. History / Change Tracking
  4. Persist to IndexedDB
  5. Local-first conflict resolution for offline caching and sync between multiple devices

Limitations

Homebase React is currently not a good choice for read-heavy applications (e.g. Twitter, ecommerce). We plan to support these query patterns with our platform eventually.

Alternatives

There isn't much in the way of React friendly datalog DB based state management for Javascript, but there's at least one alternative if you're a Clojure dev.

  • If you prefer d/pull over d/entity take a look at Posh. It supports less of the d/q API, but provides more tools for tuning performance.

Development

yarn install
yarn dev

Open http://localhost:3000

Test

yarn install
yarn test

Contributing

Welcome and thank you! Writing docs, patches and features are all incredibly helpful and appreciated.

We only ask that you provide test coverage for code changes, and conform to our commit guidelines.

Authors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Homebase React

CICDLicenseTwitter Follow

The React state management library for write-heavy applications

Supported languages, frameworks and DBs:

  • JS + React + Datascript (jump)
  • CLJS + Reagent + Datascript (jump)
  • Datahike support coming soon

What and Why

As data and our need to annotate and organize it grows, so does our need for supporting state in write-heavy applications.

To solve this problem, modern write-heavy applications such as Superhuman, Roam Research, and Facebook Messenger built their own embedded data layers to enable these more sophisticated user experiences.

Homebase-react enables developers to access the same embedded datalog database as Roam Research through React hooks. You no longer have to build out a team or learn specialized tools like Clojure in order to build a delightful write-heavy application.

Testimonials

Homebase is executing on the vision of data usage, portability, and management we had when building Firebase. We never got there. I'm excited!

—James Tamplin, Founder/CEO of Firebase

Datalog is the future of end-user programming, personal productivity software, p2p software, etc.

—Chet Corcos, Founding Engineer of Notion

Javascript + React

Start by installing homebase-react.

NPM VersionBundle Size

# NPM
npm install homebase-react --save
# Yarn
yarn add homebase-react

Optionally install the datalog-consolechrome extension to inspect the homebase-react DB in your browser.

⭐️ 📖 Read the JS docs ⚛️ ⭐️

import{useCallback}from'react'import{HomebaseProvider,useEntity,useTransact}from'homebase-react'constRootComponent=()=>(// Create a DB and set some starting data<HomebaseProviderconfig={{initialData: [{counter: {id: 1,count: 0}}]}}><App/></HomebaseProvider>)constApp=()=>{// Get entity id = 1const[counter]=useEntity(1)const[transact]=useTransact()return(<buttononClick={()=>{// Increment and save the counttransact([{counter: {id: 1,count: counter.get('count')+1}}])}>{/* Render the count */}Increment{counter.get('count')}</button>)}

Live demo

ClojureScript + Reagent

Start by adding homebase-react.

Clojars Project

Optionally add datalog-console and its corresponding chrome extension to inspect the DB in your browser.

Clojars Project

⭐️ 📖 Read the CLJS docs ƛ ⭐️

(nshomebase.dev.example.reagent.counter
(:require
[datascript.core :as d]
[homebase.reagent :as hbr]
[datalog-console.integrations.datascript :as datalog-console]))
(defdb-conn (d/create-conn {}))
(d/transact! db-conn [[:db/add1:count0]]) ; Transact some starting data.
(hbr/connect! db-conn) ; Connect homebase.reagent to the database.
(datalog-console/enable! {:conn db-conn}) ; Also connect the datalog-console extension for better debugging.
(defncounter []
(let [[entity] (hbr/entity db-conn 1)] ; Get a homebase.reagent/Entity. Note the use of db-conn and not @db-conn, this makes it reactive.
(fn []
[:div"Count: " (:count @entity) ; Deref the entity just like a reagent/atom.
[:div
[:button {:on-click #(d/transact! db-conn [[:db/add1:count (inc (:count @entity))]])} ; Use d/transact! just like normal."Increment"]]])))

Live demo

Roadmap

  1. Improve developer tools: custom chrome formatters, DB admin console extension
  2. Rewrite React ↔ Homebase cache
    1. Support async DB access (for Datahike)
    2. Reactive query planning (better perf on pages with lots of live reads)
  3. Swap Datascript out for Datahike
    1. Immutability
    2. History / Change Tracking
  4. Persist to IndexedDB
  5. Local-first conflict resolution for offline caching and sync between multiple devices

Limitations

Homebase React is currently not a good choice for read-heavy applications (e.g. Twitter, ecommerce). We plan to support these query patterns with our platform eventually.

Alternatives

There isn't much in the way of React friendly datalog DB based state management for Javascript, but there's at least one alternative if you're a Clojure dev.

  • If you prefer d/pull over d/entity take a look at Posh. It supports less of the d/q API, but provides more tools for tuning performance.

Development

yarn install
yarn dev

Open http://localhost:3000

Test

yarn install
yarn test

Contributing

Welcome and thank you! Writing docs, patches and features are all incredibly helpful and appreciated.

We only ask that you provide test coverage for code changes, and conform to our commit guidelines.

Authors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Homebase React

CICDLicenseTwitter Follow

The React state management library for write-heavy applications

Supported languages, frameworks and DBs:

  • JS + React + Datascript (jump)
  • CLJS + Reagent + Datascript (jump)
  • Datahike support coming soon

What and Why

As data and our need to annotate and organize it grows, so does our need for supporting state in write-heavy applications.

To solve this problem, modern write-heavy applications such as Superhuman, Roam Research, and Facebook Messenger built their own embedded data layers to enable these more sophisticated user experiences.

Homebase-react enables developers to access the same embedded datalog database as Roam Research through React hooks. You no longer have to build out a team or learn specialized tools like Clojure in order to build a delightful write-heavy application.

Testimonials

Homebase is executing on the vision of data usage, portability, and management we had when building Firebase. We never got there. I'm excited!

—James Tamplin, Founder/CEO of Firebase

Datalog is the future of end-user programming, personal productivity software, p2p software, etc.

—Chet Corcos, Founding Engineer of Notion

Javascript + React

Start by installing homebase-react.

NPM VersionBundle Size

# NPM
npm install homebase-react --save
# Yarn
yarn add homebase-react

Optionally install the datalog-consolechrome extension to inspect the homebase-react DB in your browser.

⭐️ 📖 Read the JS docs ⚛️ ⭐️

import{useCallback}from'react'import{HomebaseProvider,useEntity,useTransact}from'homebase-react'constRootComponent=()=>(// Create a DB and set some starting data<HomebaseProviderconfig={{initialData: [{counter: {id: 1,count: 0}}]}}><App/></HomebaseProvider>)constApp=()=>{// Get entity id = 1const[counter]=useEntity(1)const[transact]=useTransact()return(<buttononClick={()=>{// Increment and save the counttransact([{counter: {id: 1,count: counter.get('count')+1}}])}>{/* Render the count */}Increment{counter.get('count')}</button>)}

Live demo

ClojureScript + Reagent

Start by adding homebase-react.

Clojars Project

Optionally add datalog-console and its corresponding chrome extension to inspect the DB in your browser.

Clojars Project

⭐️ 📖 Read the CLJS docs ƛ ⭐️

(nshomebase.dev.example.reagent.counter
(:require
[datascript.core :as d]
[homebase.reagent :as hbr]
[datalog-console.integrations.datascript :as datalog-console]))
(defdb-conn (d/create-conn {}))
(d/transact! db-conn [[:db/add1:count0]]) ; Transact some starting data.
(hbr/connect! db-conn) ; Connect homebase.reagent to the database.
(datalog-console/enable! {:conn db-conn}) ; Also connect the datalog-console extension for better debugging.
(defncounter []
(let [[entity] (hbr/entity db-conn 1)] ; Get a homebase.reagent/Entity. Note the use of db-conn and not @db-conn, this makes it reactive.
(fn []
[:div"Count: " (:count @entity) ; Deref the entity just like a reagent/atom.
[:div
[:button {:on-click #(d/transact! db-conn [[:db/add1:count (inc (:count @entity))]])} ; Use d/transact! just like normal."Increment"]]])))

Live demo

Roadmap

  1. Improve developer tools: custom chrome formatters, DB admin console extension
  2. Rewrite React ↔ Homebase cache
    1. Support async DB access (for Datahike)
    2. Reactive query planning (better perf on pages with lots of live reads)
  3. Swap Datascript out for Datahike
    1. Immutability
    2. History / Change Tracking
  4. Persist to IndexedDB
  5. Local-first conflict resolution for offline caching and sync between multiple devices

Limitations

Homebase React is currently not a good choice for read-heavy applications (e.g. Twitter, ecommerce). We plan to support these query patterns with our platform eventually.

Alternatives

There isn't much in the way of React friendly datalog DB based state management for Javascript, but there's at least one alternative if you're a Clojure dev.

  • If you prefer d/pull over d/entity take a look at Posh. It supports less of the d/q API, but provides more tools for tuning performance.

Development

yarn install
yarn dev

Open http://localhost:3000

Test

yarn install
yarn test

Contributing

Welcome and thank you! Writing docs, patches and features are all incredibly helpful and appreciated.

We only ask that you provide test coverage for code changes, and conform to our commit guidelines.

Authors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Homebase React

CICDLicenseTwitter Follow

The React state management library for write-heavy applications

Supported languages, frameworks and DBs:

  • JS + React + Datascript (jump)
  • CLJS + Reagent + Datascript (jump)
  • Datahike support coming soon

What and Why

As data and our need to annotate and organize it grows, so does our need for supporting state in write-heavy applications.

To solve this problem, modern write-heavy applications such as Superhuman, Roam Research, and Facebook Messenger built their own embedded data layers to enable these more sophisticated user experiences.

Homebase-react enables developers to access the same embedded datalog database as Roam Research through React hooks. You no longer have to build out a team or learn specialized tools like Clojure in order to build a delightful write-heavy application.

Testimonials

Homebase is executing on the vision of data usage, portability, and management we had when building Firebase. We never got there. I'm excited!

—James Tamplin, Founder/CEO of Firebase

Datalog is the future of end-user programming, personal productivity software, p2p software, etc.

—Chet Corcos, Founding Engineer of Notion

Javascript + React

Start by installing homebase-react.

NPM VersionBundle Size

# NPM
npm install homebase-react --save
# Yarn
yarn add homebase-react

Optionally install the datalog-consolechrome extension to inspect the homebase-react DB in your browser.

⭐️ 📖 Read the JS docs ⚛️ ⭐️

import{useCallback}from'react'import{HomebaseProvider,useEntity,useTransact}from'homebase-react'constRootComponent=()=>(// Create a DB and set some starting data<HomebaseProviderconfig={{initialData: [{counter: {id: 1,count: 0}}]}}><App/></HomebaseProvider>)constApp=()=>{// Get entity id = 1const[counter]=useEntity(1)const[transact]=useTransact()return(<buttononClick={()=>{// Increment and save the counttransact([{counter: {id: 1,count: counter.get('count')+1}}])}>{/* Render the count */}Increment{counter.get('count')}</button>)}

Live demo

ClojureScript + Reagent

Start by adding homebase-react.

Clojars Project

Optionally add datalog-console and its corresponding chrome extension to inspect the DB in your browser.

Clojars Project

⭐️ 📖 Read the CLJS docs ƛ ⭐️

(nshomebase.dev.example.reagent.counter
(:require
[datascript.core :as d]
[homebase.reagent :as hbr]
[datalog-console.integrations.datascript :as datalog-console]))
(defdb-conn (d/create-conn {}))
(d/transact! db-conn [[:db/add1:count0]]) ; Transact some starting data.
(hbr/connect! db-conn) ; Connect homebase.reagent to the database.
(datalog-console/enable! {:conn db-conn}) ; Also connect the datalog-console extension for better debugging.
(defncounter []
(let [[entity] (hbr/entity db-conn 1)] ; Get a homebase.reagent/Entity. Note the use of db-conn and not @db-conn, this makes it reactive.
(fn []
[:div"Count: " (:count @entity) ; Deref the entity just like a reagent/atom.
[:div
[:button {:on-click #(d/transact! db-conn [[:db/add1:count (inc (:count @entity))]])} ; Use d/transact! just like normal."Increment"]]])))

Live demo

Roadmap

  1. Improve developer tools: custom chrome formatters, DB admin console extension
  2. Rewrite React ↔ Homebase cache
    1. Support async DB access (for Datahike)
    2. Reactive query planning (better perf on pages with lots of live reads)
  3. Swap Datascript out for Datahike
    1. Immutability
    2. History / Change Tracking
  4. Persist to IndexedDB
  5. Local-first conflict resolution for offline caching and sync between multiple devices

Limitations

Homebase React is currently not a good choice for read-heavy applications (e.g. Twitter, ecommerce). We plan to support these query patterns with our platform eventually.

Alternatives

There isn't much in the way of React friendly datalog DB based state management for Javascript, but there's at least one alternative if you're a Clojure dev.

  • If you prefer d/pull over d/entity take a look at Posh. It supports less of the d/q API, but provides more tools for tuning performance.

Development

yarn install
yarn dev

Open http://localhost:3000

Test

yarn install
yarn test

Contributing

Welcome and thank you! Writing docs, patches and features are all incredibly helpful and appreciated.

We only ask that you provide test coverage for code changes, and conform to our commit guidelines.

Authors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Homebase React

CICDLicenseTwitter Follow

The React state management library for write-heavy applications

Supported languages, frameworks and DBs:

  • JS + React + Datascript (jump)
  • CLJS + Reagent + Datascript (jump)
  • Datahike support coming soon

What and Why

As data and our need to annotate and organize it grows, so does our need for supporting state in write-heavy applications.

To solve this problem, modern write-heavy applications such as Superhuman, Roam Research, and Facebook Messenger built their own embedded data layers to enable these more sophisticated user experiences.

Homebase-react enables developers to access the same embedded datalog database as Roam Research through React hooks. You no longer have to build out a team or learn specialized tools like Clojure in order to build a delightful write-heavy application.

Testimonials

Homebase is executing on the vision of data usage, portability, and management we had when building Firebase. We never got there. I'm excited!

—James Tamplin, Founder/CEO of Firebase

Datalog is the future of end-user programming, personal productivity software, p2p software, etc.

—Chet Corcos, Founding Engineer of Notion

Javascript + React

Start by installing homebase-react.

NPM VersionBundle Size

# NPM
npm install homebase-react --save
# Yarn
yarn add homebase-react

Optionally install the datalog-consolechrome extension to inspect the homebase-react DB in your browser.

⭐️ 📖 Read the JS docs ⚛️ ⭐️

import{useCallback}from'react'import{HomebaseProvider,useEntity,useTransact}from'homebase-react'constRootComponent=()=>(// Create a DB and set some starting data<HomebaseProviderconfig={{initialData: [{counter: {id: 1,count: 0}}]}}><App/></HomebaseProvider>)constApp=()=>{// Get entity id = 1const[counter]=useEntity(1)const[transact]=useTransact()return(<buttononClick={()=>{// Increment and save the counttransact([{counter: {id: 1,count: counter.get('count')+1}}])}>{/* Render the count */}Increment{counter.get('count')}</button>)}

Live demo

ClojureScript + Reagent

Start by adding homebase-react.

Clojars Project

Optionally add datalog-console and its corresponding chrome extension to inspect the DB in your browser.

Clojars Project

⭐️ 📖 Read the CLJS docs ƛ ⭐️

(nshomebase.dev.example.reagent.counter
(:require
[datascript.core :as d]
[homebase.reagent :as hbr]
[datalog-console.integrations.datascript :as datalog-console]))
(defdb-conn (d/create-conn {}))
(d/transact! db-conn [[:db/add1:count0]]) ; Transact some starting data.
(hbr/connect! db-conn) ; Connect homebase.reagent to the database.
(datalog-console/enable! {:conn db-conn}) ; Also connect the datalog-console extension for better debugging.
(defncounter []
(let [[entity] (hbr/entity db-conn 1)] ; Get a homebase.reagent/Entity. Note the use of db-conn and not @db-conn, this makes it reactive.
(fn []
[:div"Count: " (:count @entity) ; Deref the entity just like a reagent/atom.
[:div
[:button {:on-click #(d/transact! db-conn [[:db/add1:count (inc (:count @entity))]])} ; Use d/transact! just like normal."Increment"]]])))

Live demo

Roadmap

  1. Improve developer tools: custom chrome formatters, DB admin console extension
  2. Rewrite React ↔ Homebase cache
    1. Support async DB access (for Datahike)
    2. Reactive query planning (better perf on pages with lots of live reads)
  3. Swap Datascript out for Datahike
    1. Immutability
    2. History / Change Tracking
  4. Persist to IndexedDB
  5. Local-first conflict resolution for offline caching and sync between multiple devices

Limitations

Homebase React is currently not a good choice for read-heavy applications (e.g. Twitter, ecommerce). We plan to support these query patterns with our platform eventually.

Alternatives

There isn't much in the way of React friendly datalog DB based state management for Javascript, but there's at least one alternative if you're a Clojure dev.

  • If you prefer d/pull over d/entity take a look at Posh. It supports less of the d/q API, but provides more tools for tuning performance.

Development

yarn install
yarn dev

Open http://localhost:3000

Test

yarn install
yarn test

Contributing

Welcome and thank you! Writing docs, patches and features are all incredibly helpful and appreciated.

We only ask that you provide test coverage for code changes, and conform to our commit guidelines.

Authors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Homebase React

CICDLicenseTwitter Follow

The React state management library for write-heavy applications

Supported languages, frameworks and DBs:

  • JS + React + Datascript (jump)
  • CLJS + Reagent + Datascript (jump)
  • Datahike support coming soon

What and Why

As data and our need to annotate and organize it grows, so does our need for supporting state in write-heavy applications.

To solve this problem, modern write-heavy applications such as Superhuman, Roam Research, and Facebook Messenger built their own embedded data layers to enable these more sophisticated user experiences.

Homebase-react enables developers to access the same embedded datalog database as Roam Research through React hooks. You no longer have to build out a team or learn specialized tools like Clojure in order to build a delightful write-heavy application.

Testimonials

Homebase is executing on the vision of data usage, portability, and management we had when building Firebase. We never got there. I'm excited!

—James Tamplin, Founder/CEO of Firebase

Datalog is the future of end-user programming, personal productivity software, p2p software, etc.

—Chet Corcos, Founding Engineer of Notion

Javascript + React

Start by installing homebase-react.

NPM VersionBundle Size

# NPM
npm install homebase-react --save
# Yarn
yarn add homebase-react

Optionally install the datalog-consolechrome extension to inspect the homebase-react DB in your browser.

⭐️ 📖 Read the JS docs ⚛️ ⭐️

import{useCallback}from'react'import{HomebaseProvider,useEntity,useTransact}from'homebase-react'constRootComponent=()=>(// Create a DB and set some starting data<HomebaseProviderconfig={{initialData: [{counter: {id: 1,count: 0}}]}}><App/></HomebaseProvider>)constApp=()=>{// Get entity id = 1const[counter]=useEntity(1)const[transact]=useTransact()return(<buttononClick={()=>{// Increment and save the counttransact([{counter: {id: 1,count: counter.get('count')+1}}])}>{/* Render the count */}Increment{counter.get('count')}</button>)}

Live demo

ClojureScript + Reagent

Start by adding homebase-react.

Clojars Project

Optionally add datalog-console and its corresponding chrome extension to inspect the DB in your browser.

Clojars Project

⭐️ 📖 Read the CLJS docs ƛ ⭐️

(nshomebase.dev.example.reagent.counter
(:require
[datascript.core :as d]
[homebase.reagent :as hbr]
[datalog-console.integrations.datascript :as datalog-console]))
(defdb-conn (d/create-conn {}))
(d/transact! db-conn [[:db/add1:count0]]) ; Transact some starting data.
(hbr/connect! db-conn) ; Connect homebase.reagent to the database.
(datalog-console/enable! {:conn db-conn}) ; Also connect the datalog-console extension for better debugging.
(defncounter []
(let [[entity] (hbr/entity db-conn 1)] ; Get a homebase.reagent/Entity. Note the use of db-conn and not @db-conn, this makes it reactive.
(fn []
[:div"Count: " (:count @entity) ; Deref the entity just like a reagent/atom.
[:div
[:button {:on-click #(d/transact! db-conn [[:db/add1:count (inc (:count @entity))]])} ; Use d/transact! just like normal."Increment"]]])))

Live demo

Roadmap

  1. Improve developer tools: custom chrome formatters, DB admin console extension
  2. Rewrite React ↔ Homebase cache
    1. Support async DB access (for Datahike)
    2. Reactive query planning (better perf on pages with lots of live reads)
  3. Swap Datascript out for Datahike
    1. Immutability
    2. History / Change Tracking
  4. Persist to IndexedDB
  5. Local-first conflict resolution for offline caching and sync between multiple devices

Limitations

Homebase React is currently not a good choice for read-heavy applications (e.g. Twitter, ecommerce). We plan to support these query patterns with our platform eventually.

Alternatives

There isn't much in the way of React friendly datalog DB based state management for Javascript, but there's at least one alternative if you're a Clojure dev.

  • If you prefer d/pull over d/entity take a look at Posh. It supports less of the d/q API, but provides more tools for tuning performance.

Development

yarn install
yarn dev

Open http://localhost:3000

Test

yarn install
yarn test

Contributing

Welcome and thank you! Writing docs, patches and features are all incredibly helpful and appreciated.

We only ask that you provide test coverage for code changes, and conform to our commit guidelines.

Authors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Homebase React

CICDLicenseTwitter Follow

The React state management library for write-heavy applications

Supported languages, frameworks and DBs:

  • JS + React + Datascript (jump)
  • CLJS + Reagent + Datascript (jump)
  • Datahike support coming soon

What and Why

As data and our need to annotate and organize it grows, so does our need for supporting state in write-heavy applications.

To solve this problem, modern write-heavy applications such as Superhuman, Roam Research, and Facebook Messenger built their own embedded data layers to enable these more sophisticated user experiences.

Homebase-react enables developers to access the same embedded datalog database as Roam Research through React hooks. You no longer have to build out a team or learn specialized tools like Clojure in order to build a delightful write-heavy application.

Testimonials

Homebase is executing on the vision of data usage, portability, and management we had when building Firebase. We never got there. I'm excited!

—James Tamplin, Founder/CEO of Firebase

Datalog is the future of end-user programming, personal productivity software, p2p software, etc.

—Chet Corcos, Founding Engineer of Notion

Javascript + React

Start by installing homebase-react.

NPM VersionBundle Size

# NPM
npm install homebase-react --save
# Yarn
yarn add homebase-react

Optionally install the datalog-consolechrome extension to inspect the homebase-react DB in your browser.

⭐️ 📖 Read the JS docs ⚛️ ⭐️

import{useCallback}from'react'import{HomebaseProvider,useEntity,useTransact}from'homebase-react'constRootComponent=()=>(// Create a DB and set some starting data<HomebaseProviderconfig={{initialData: [{counter: {id: 1,count: 0}}]}}><App/></HomebaseProvider>)constApp=()=>{// Get entity id = 1const[counter]=useEntity(1)const[transact]=useTransact()return(<buttononClick={()=>{// Increment and save the counttransact([{counter: {id: 1,count: counter.get('count')+1}}])}>{/* Render the count */}Increment{counter.get('count')}</button>)}

Live demo

ClojureScript + Reagent

Start by adding homebase-react.

Clojars Project

Optionally add datalog-console and its corresponding chrome extension to inspect the DB in your browser.

Clojars Project

⭐️ 📖 Read the CLJS docs ƛ ⭐️

(nshomebase.dev.example.reagent.counter
(:require
[datascript.core :as d]
[homebase.reagent :as hbr]
[datalog-console.integrations.datascript :as datalog-console]))
(defdb-conn (d/create-conn {}))
(d/transact! db-conn [[:db/add1:count0]]) ; Transact some starting data.
(hbr/connect! db-conn) ; Connect homebase.reagent to the database.
(datalog-console/enable! {:conn db-conn}) ; Also connect the datalog-console extension for better debugging.
(defncounter []
(let [[entity] (hbr/entity db-conn 1)] ; Get a homebase.reagent/Entity. Note the use of db-conn and not @db-conn, this makes it reactive.
(fn []
[:div"Count: " (:count @entity) ; Deref the entity just like a reagent/atom.
[:div
[:button {:on-click #(d/transact! db-conn [[:db/add1:count (inc (:count @entity))]])} ; Use d/transact! just like normal."Increment"]]])))

Live demo

Roadmap

  1. Improve developer tools: custom chrome formatters, DB admin console extension
  2. Rewrite React ↔ Homebase cache
    1. Support async DB access (for Datahike)
    2. Reactive query planning (better perf on pages with lots of live reads)
  3. Swap Datascript out for Datahike
    1. Immutability
    2. History / Change Tracking
  4. Persist to IndexedDB
  5. Local-first conflict resolution for offline caching and sync between multiple devices

Limitations

Homebase React is currently not a good choice for read-heavy applications (e.g. Twitter, ecommerce). We plan to support these query patterns with our platform eventually.

Alternatives

There isn't much in the way of React friendly datalog DB based state management for Javascript, but there's at least one alternative if you're a Clojure dev.

  • If you prefer d/pull over d/entity take a look at Posh. It supports less of the d/q API, but provides more tools for tuning performance.

Development

yarn install
yarn dev

Open http://localhost:3000

Test

yarn install
yarn test

Contributing

Welcome and thank you! Writing docs, patches and features are all incredibly helpful and appreciated.

We only ask that you provide test coverage for code changes, and conform to our commit guidelines.

Authors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Homebase React

CICDLicenseTwitter Follow

The React state management library for write-heavy applications

Supported languages, frameworks and DBs:

  • JS + React + Datascript (jump)
  • CLJS + Reagent + Datascript (jump)
  • Datahike support coming soon

What and Why

As data and our need to annotate and organize it grows, so does our need for supporting state in write-heavy applications.

To solve this problem, modern write-heavy applications such as Superhuman, Roam Research, and Facebook Messenger built their own embedded data layers to enable these more sophisticated user experiences.

Homebase-react enables developers to access the same embedded datalog database as Roam Research through React hooks. You no longer have to build out a team or learn specialized tools like Clojure in order to build a delightful write-heavy application.

Testimonials

Homebase is executing on the vision of data usage, portability, and management we had when building Firebase. We never got there. I'm excited!

—James Tamplin, Founder/CEO of Firebase

Datalog is the future of end-user programming, personal productivity software, p2p software, etc.

—Chet Corcos, Founding Engineer of Notion

Javascript + React

Start by installing homebase-react.

NPM VersionBundle Size

# NPM
npm install homebase-react --save
# Yarn
yarn add homebase-react

Optionally install the datalog-consolechrome extension to inspect the homebase-react DB in your browser.

⭐️ 📖 Read the JS docs ⚛️ ⭐️

import{useCallback}from'react'import{HomebaseProvider,useEntity,useTransact}from'homebase-react'constRootComponent=()=>(// Create a DB and set some starting data<HomebaseProviderconfig={{initialData: [{counter: {id: 1,count: 0}}]}}><App/></HomebaseProvider>)constApp=()=>{// Get entity id = 1const[counter]=useEntity(1)const[transact]=useTransact()return(<buttononClick={()=>{// Increment and save the counttransact([{counter: {id: 1,count: counter.get('count')+1}}])}>{/* Render the count */}Increment{counter.get('count')}</button>)}

Live demo

ClojureScript + Reagent

Start by adding homebase-react.

Clojars Project

Optionally add datalog-console and its corresponding chrome extension to inspect the DB in your browser.

Clojars Project

⭐️ 📖 Read the CLJS docs ƛ ⭐️

(nshomebase.dev.example.reagent.counter
(:require
[datascript.core :as d]
[homebase.reagent :as hbr]
[datalog-console.integrations.datascript :as datalog-console]))
(defdb-conn (d/create-conn {}))
(d/transact! db-conn [[:db/add1:count0]]) ; Transact some starting data.
(hbr/connect! db-conn) ; Connect homebase.reagent to the database.
(datalog-console/enable! {:conn db-conn}) ; Also connect the datalog-console extension for better debugging.
(defncounter []
(let [[entity] (hbr/entity db-conn 1)] ; Get a homebase.reagent/Entity. Note the use of db-conn and not @db-conn, this makes it reactive.
(fn []
[:div"Count: " (:count @entity) ; Deref the entity just like a reagent/atom.
[:div
[:button {:on-click #(d/transact! db-conn [[:db/add1:count (inc (:count @entity))]])} ; Use d/transact! just like normal."Increment"]]])))

Live demo

Roadmap

  1. Improve developer tools: custom chrome formatters, DB admin console extension
  2. Rewrite React ↔ Homebase cache
    1. Support async DB access (for Datahike)
    2. Reactive query planning (better perf on pages with lots of live reads)
  3. Swap Datascript out for Datahike
    1. Immutability
    2. History / Change Tracking
  4. Persist to IndexedDB
  5. Local-first conflict resolution for offline caching and sync between multiple devices

Limitations

Homebase React is currently not a good choice for read-heavy applications (e.g. Twitter, ecommerce). We plan to support these query patterns with our platform eventually.

Alternatives

There isn't much in the way of React friendly datalog DB based state management for Javascript, but there's at least one alternative if you're a Clojure dev.

  • If you prefer d/pull over d/entity take a look at Posh. It supports less of the d/q API, but provides more tools for tuning performance.

Development

yarn install
yarn dev

Open http://localhost:3000

Test

yarn install
yarn test

Contributing

Welcome and thank you! Writing docs, patches and features are all incredibly helpful and appreciated.

We only ask that you provide test coverage for code changes, and conform to our commit guidelines.

Authors