Something went wrong. Try again.
A lexicon-driven AppView for ATProto.
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061<!doctype html><html lang="en" dir="ltr" class="docs-wrapper plugin-docs plugin-id-default docs-version-current docs-doc-page docs-doc-id-README" data-has-hydrated="false"><head><meta charset="UTF-8"><meta name="generator" content="Docusaurus v3.10.0"><title data-rh="true">HappyView</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:image" content="https://happyview.dev/img/og.png"><meta data-rh="true" name="twitter:image" content="https://happyview.dev/img/og.png"><meta data-rh="true" property="og:url" content="https://happyview.dev/"><meta data-rh="true" property="og:locale" content="en"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-default-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-rh="true" property="og:title" content="HappyView"><meta data-rh="true" name="description" content="HappyView is the best way to build an AppView for the AT Protocol. Upload your lexicon schemas and get a fully functional AppView, complete with XRPC endpoints, OAuth, real-time network sync, and historical backfill, without writing a single line of server code."><meta data-rh="true" property="og:description" content="HappyView is the best way to build an AppView for the AT Protocol. Upload your lexicon schemas and get a fully functional AppView, complete with XRPC endpoints, OAuth, real-time network sync, and historical backfill, without writing a single line of server code."><link data-rh="true" rel="icon" href="/img/favicon.png"><link data-rh="true" rel="canonical" href="https://happyview.dev/"><link data-rh="true" rel="alternate" href="https://happyview.dev/" hreflang="en"><link data-rh="true" rel="alternate" href="https://happyview.dev/" hreflang="x-default"><script data-rh="true">function insertBanner(){var n=document.createElement("div");n.id="__docusaurus-base-url-issue-banner-container";n.innerHTML='\n<div id="__docusaurus-base-url-issue-banner" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">/</span> (default value)</p>\n <p>We suggest trying baseUrl = <span id="__docusaurus-base-url-issue-banner-suggestion-container" style="font-weight: bold; color: green;"></span></p>\n</div>\n',document.body.prepend(n);var e=document.getElementById("__docusaurus-base-url-issue-banner-suggestion-container"),s=window.location.pathname,o="/"===s.substr(-1)?s:s+"/";e.innerHTML=o}document.addEventListener("DOMContentLoaded",function(){void 0===window.docusaurus&&insertBanner()})</script><script data-rh="true" type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Introduction","item":"https://happyview.dev/"}]}</script><link rel="stylesheet" href="/assets/css/styles.18b9c377.css"><script src="/assets/js/runtime~main.413aac68.js" defer="defer"></script><script src="/assets/js/main.c991874c.js" defer="defer"></script></head><body><svg style="display: none;"><defs><symbol id="theme-svg-external-link" viewBox="0 0 24 24"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></symbol></defs></svg><script>!function(){var t=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return window.localStorage.getItem("theme")}catch(t){}}();document.documentElement.setAttribute("data-theme",t||"light"),document.documentElement.setAttribute("data-theme-choice",t||"light")}(),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id="__docusaurus"><link rel="preload" as="image" href="/img/logo.light.png"><link rel="preload" as="image" href="/img/logo.dark.png"><div role="region" aria-label="Skip to main content"><a class="skipToContent_hn_G" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="theme-layout-navbar navbar navbar--fixed-top"><div class="navbar__inner"><div class="theme-layout-navbar-left navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/img/logo.light.png" alt="HappyView" class="themedComponent_EfZ_ themedComponent--light_EnZ3"><img src="/img/logo.dark.png" alt="HappyView" class="themedComponent_EfZ_ themedComponent--dark_UTRq"></div><b class="navbar__title text--truncate"></b></a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/">Docs</a></div><div class="theme-layout-navbar-right navbar__items navbar__items--right"><a href="https://github.com/gamesgamesgamesgamesgames/happyview" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">GitHub<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_yqny"><use href="#theme-svg-external-link"></use></svg></a><div class="toggle_pDN8 colorModeToggle_WR5U"><button class="clean-btn toggleButton__Co1 toggleButtonDisabled_pTNf" type="button" disabled="" title="system mode" aria-label="Switch between dark and light mode (currently system mode)"><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_IF_c lightToggleIcon_z1QC"><path fill="currentColor" d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_IF_c darkToggleIcon_O_bk"><path fill="currentColor" d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_IF_c systemToggleIcon_SKeC"><path fill="currentColor" d="m12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9zm4.95-13.95c1.313 1.313 2.05 3.093 2.05 4.95s-0.738 3.637-2.05 4.95c-1.313 1.313-3.093 2.05-4.95 2.05v-14c1.857 0 3.637 0.737 4.95 2.05z"></path></svg></button></div><div class="navbarSearchContainer_qQFS"></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="theme-layout-main main-wrapper mainWrapper_NcQk"><div class="docsWrapper_tjyD"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_J6bC" type="button"></button><div class="docRoot_mCS9"><aside class="theme-doc-sidebar-container docSidebarContainer_AIvH"><div class="sidebarViewport_v5_F"><div class="sidebar_TbVu"><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_hz51"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" href="/"><span title="Introduction" class="linkLabel_GBZK">Introduction</span></a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_RHuM menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/getting-started/quickstart"><span title="Getting Started" class="categoryLinkLabel_ppUb">Getting Started</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_RHuM menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/tutorials/statusphere"><span title="Tutorials" class="categoryLinkLabel_ppUb">Tutorials</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_RHuM menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/guides/lexicons"><span title="Guides" class="categoryLinkLabel_ppUb">Guides</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_RHuM menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/sdk/overview"><span title="JavaScript SDK" class="categoryLinkLabel_ppUb">JavaScript SDK</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_RHuM menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/reference/xrpc-api"><span title="Reference" class="categoryLinkLabel_ppUb">Reference</span></a></div></li></ul></nav></div></div></aside><main class="docMainContainer_Gcuv"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_SLVn"><div class="docItemContainer_gUK8"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer__5rh" aria-label="Breadcrumbs"><ul class="breadcrumbs"><li class="breadcrumbs__item"><a aria-label="Home page" class="breadcrumbs__link" href="/"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_ilNI"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link">Introduction</span></li></ul></nav><div class="tocCollapsible_vaUl theme-doc-toc-mobile tocMobile_CcuZ"><button type="button" class="clean-btn tocCollapsibleButton__AHn">On this page</button></div><div class="theme-doc-markdown markdown"><header><h1>HappyView</h1></header><p>HappyView is the best way to build an <a href="https://atproto.com/guides/glossary#app-view" target="_blank" rel="noopener noreferrer" class="">AppView</a> for the <a href="https://atproto.com" target="_blank" rel="noopener noreferrer" class="">AT Protocol</a>. Upload your <a class="" href="/reference/glossary#atproto-terms">lexicon</a> schemas and get a fully functional AppView, complete with <a class="" href="/reference/glossary#atproto-terms">XRPC</a> endpoints, OAuth, real-time network sync, and historical <a class="" href="/guides/backfill">backfill</a>, without writing a single line of server code.</p><p>Building an AppView from scratch means wiring up real-time event streams, record storage, XRPC routing, OAuth flows, and PDS write proxying before you can even think about your application. HappyView handles all of that. Define your data model with lexicons, add custom logic with Lua scripts when you need it, and ship your app.</p><h2 class="anchor anchorTargetStickyNavbar_zGuS" id="features">Features<a href="#features" class="hash-link" aria-label="Direct link to Features" title="Direct link to Features" translate="no"></a></h2><ul><li class=""><p><strong>Schema-driven endpoints:</strong> Upload a <a class="" href="/guides/lexicons">lexicon</a> and HappyView generates XRPC query and procedure routes, storage, and indexing from it — updatable at runtime with no restart.</p></li><li class=""><p><strong>Network sync built in:</strong> Real-time record streaming via <a href="https://github.com/bluesky-social/jetstream" target="_blank" rel="noopener noreferrer" class="">Jetstream</a>, historical <a class="" href="/guides/backfill">backfill</a> from each user's PDS, and atproto OAuth with DPoP-bound proxy writes back to the PDS.</p></li><li class=""><p><strong>Customize with Lua, hooks, and plugins:</strong> <a class="" href="/guides/scripting">Lua scripts</a> for query and procedure logic, <a class="" href="/guides/index-hooks">index hooks</a> that fire on every record change, WASM <a class="" href="/guides/plugins">plugins</a> for external platform integration, and <a class="" href="/guides/labelers">labeler</a> subscriptions for content moderation.</p></li><li class=""><p><strong>Protocol-native:</strong> Works with any PDS, resolves DIDs through the directory, and fetches <a class="" href="/guides/lexicons#network-lexicons">network lexicons</a> via DNS authority resolution.</p></li><li class=""><p><strong>Full admin surface:</strong> Built-in <a class="" href="/getting-started/dashboard">dashboard</a> and <a class="" href="/reference/admin-api">admin API</a> for managing lexicons, users, API keys, API clients, backfill jobs, and plugins.</p></li></ul><h2 class="anchor anchorTargetStickyNavbar_zGuS" id="design-principles">Design Principles<a href="#design-principles" class="hash-link" aria-label="Direct link to Design Principles" title="Direct link to Design Principles" translate="no"></a></h2><ul><li class=""><p><strong>Schema-first</strong>: Your Lexicons are the source of truth. Upload a schema and HappyView derives endpoints, indexing rules, and network sync from it. You describe <em>what</em> your data looks like; HappyView figures out the rest.</p></li><li class=""><p><strong>Zero boilerplate</strong>: HappyView handles AppView infrastructure (Jetstream, backfill, OAuth, PDS proxying) for you. You should be writing application logic from minute one, not plumbing.</p></li><li class=""><p><strong>Runtime-configurable</strong>: Lexicons can be added, updated, and removed without restarting the server. New endpoints and sync rules take effect immediately, so you can iterate on your data model in real time.</p></li><li class=""><p><strong>Protocol-native</strong>: HappyView works with <em>any</em> PDS, resolves DIDs through the directory, and follows atproto conventions. It's a first-class citizen of the network, not a wrapper around it.</p></li></ul><h2 class="anchor anchorTargetStickyNavbar_zGuS" id="next-steps">Next Steps<a href="#next-steps" class="hash-link" aria-label="Direct link to Next Steps" title="Direct link to Next Steps" translate="no"></a></h2><ul><li class=""><a class="" href="/getting-started/deployment/railway">Quickstart</a>: Deploy HappyView on Railway or run it locally</li><li class=""><a class="" href="/guides/lexicons">Lexicons</a>: Upload lexicon schemas and start indexing records</li><li class=""><a class="" href="/guides/scripting">Lua Scripting</a>: Write custom query and procedure logic</li><li class=""><a class="" href="/guides/index-hooks">Index Hooks</a>: React to record changes in real time</li><li class=""><a class="" href="/guides/labelers">Labelers</a>: Subscribe to external labelers and manage content labels</li><li class=""><a class="" href="/guides/plugins">Plugins</a>: Integrate with external platforms using WASM plugins</li><li class=""><a class="" href="/guides/event-logs">Event Logs</a>: Monitor system activity, debug script errors, and audit admin actions</li></ul></div></article><nav class="docusaurus-mt-lg pagination-nav" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--next" href="/getting-started/quickstart"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Quickstart</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_X45M thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#features" class="table-of-contents__link toc-highlight">Features</a></li><li><a href="#design-principles" class="table-of-contents__link toc-highlight">Design Principles</a></li><li><a href="#next-steps" class="table-of-contents__link toc-highlight">Next Steps</a></li></ul></div></div></div></div></main></div></div></div><footer class="theme-layout-footer footer"><div class="container container-fluid"><div class="footer__bottom text--center"><div class="footer__copyright">Copyright © 2026 <a href="https://birb.house">Birbhouse Games</a>.</div></div></div></footer></div></body></html>