Inertia resolves a page by name: a controller call like Inertia::render('Dashboard', [...]) matches resources/js/Pages/Dashboard.tsx. The array of props the controller passes in becomes that page component’s props — there’s no separate client-side data fetch for the page’s initial data.Orbit’s pages: Dashboard, Projects/Index, Projects/Show (the main project workspace — filter bar plus the List/Board/Calendar switcher), Issues/Show (a single issue’s detail page), Settings/Index (see Settings), and Auth/Login / Auth/Register.
GuestLayout wraps the unauthenticated auth pages. MainLayout wraps everything else — sidebar, top navigation, and the current project/view context passed down to child pages.
Context (resources/js/context/) — AlertContext for toast messages (including flash messages from a redirect), ModalContext for orchestrating whichever modal is currently open, ShortcutContext for keyboard shortcuts, ThemeContext and AccentContext for the theme and accent color, both mounted at the root of app.tsx so they’re available everywhere
Hooks (resources/js/hooks/) — useSavedFilters wraps saved-filter CRUD and applying a filter’s query params; useTableResizing handles resizable columns in the List view
Some fields in types/Issues.ts (like milestone, sprint, or attachments_count) aren’t backed by any database column — they’re speculative additions to the type that don’t reflect a real, working feature. Don’t take the presence of a TypeScript field as confirmation a feature exists; check the issues table and IssueController before documenting or relying on it.
Tailwind CSS, with class-variance-authority for component variants and a cn() helper (clsx + tailwind-merge) for combining classes. Colors come from CSS custom properties (--bg-color, --accent-color, --border-color, and so on) consumed as Tailwind arbitrary values like bg-[var(--bg-color)], rather than Tailwind’s built-in color palette — see Appearance for the full token list and how Light/Dark/System theme switching works.
@/ resolves to resources/js/ (configured in both tsconfig.json and the Vite config), so imports read as @/Components/Atoms/Button rather than long relative paths.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Orbit","description":"Orbit is a modern project management platform focused on simplicity, performance, and complete control over your data.","colors":{"primary":"#8844DA","light":"#B767FF","dark":"#6A2FB8"},"logo":{"light":"https://mintcdn.com/orbitdev/RavC4algsRMlwGCe/logo/logo.png?fit=max\u0026auto=format\u0026n=RavC4algsRMlwGCe\u0026q=85\u0026s=ac954893e8902e9a3843245b5916ebe2","dark":"https://mintcdn.com/orbitdev/RavC4algsRMlwGCe/logo/logo.png?fit=max\u0026auto=format\u0026n=RavC4algsRMlwGCe\u0026q=85\u0026s=ac954893e8902e9a3843245b5916ebe2"},"favicon":"https://mintcdn.com/orbitdev/n0N1HG4mmfyqhUr2/favicon.png?fit=max\u0026auto=format\u0026n=n0N1HG4mmfyqhUr2\u0026q=85\u0026s=d9de5d616ebbee7d6a842364e0f6170a","navbar":{"links":[{"href":"https://github.com/orbit-collective/orbit","label":"GitHub"}],"primary":{"type":"button","label":"Quickstart","href":"/quickstart"}},"footer":{"socials":{"github":"https://github.com/orbit-collective"}},"search":{"prompt":"Search in Orbit docs"},"seo":{"metatags":{"og:site_name":"Orbit"},"indexing":"all"},"styling":{"eyebrows":"section","latex":true},"contextual":{"options":["copy","view","chatgpt","claude","mcp"],"display":"header"},"metadata":{"timestamp":true},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"orbitdev","hasAudioNarration":false,"actualSubdomain":"orbitdev","customDomains":["docs.orbit-dev.app"],"gitSource":{"type":"github","owner":"orbit-collective","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"chroma":{"latestBuiltDeploymentHistoryId":"6ab7a48ae550855a13a63465","collectionId":"0f3e10ae-4a49-4243-a31f-d3f4d7c12b73","liveDeploymentHistoryId":"6ab7a48ae550855a13a63465","schemaVersion":"v3"},"feedback":{"issues":true,"edits":true,"thumbs":true},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6ab7a48ae550855a13a63465","clientVersion":"0.0.3990","searchFilterCounts":[{"language":"default","tag":"Guides","count":13},{"language":"default","tag":"Core Concepts","count":11},{"language":"default","tag":"Architecture","count":6},{"language":"default","tag":"Deployment","count":3},{"language":"default","tag":"Reference","count":3},{"language":"default","tag":"Get Started","count":2}],"searchSettings":{"isFiltersEnabled":true}},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"privacy":{"consentBanner":{"enabled":true}},"isAtlas":false,"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"architecture/frontend-architecture","slug":"/architecture/frontend-architecture","pageMetadata":{"title":"Frontend architecture","description":"Inertia pages, atomic-design components, and where shared logic lives","href":"/architecture/frontend-architecture"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Inertia pages, atomic-design components, and where shared logic lives\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{Heading,Warning}=_components;if(!Heading)_missingMdxReference(`Heading`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`The frontend is React 19 with TypeScript, rendered through Inertia rather than fetched from an API.`}),`\n`,_jsx(Heading,{level:`2`,id:`pages`,children:`Pages`}),`\n`,_jsxs(_components.p,{children:[`Inertia resolves a page by name: a controller call like `,_jsx(_components.code,{children:`Inertia::render('Dashboard', [...])`}),` matches `,_jsx(_components.code,{children:`resources/js/Pages/Dashboard.tsx`}),`. The array of props the controller passes in becomes that page component’s props — there’s no separate client-side data fetch for the page’s initial data.`]}),`\n`,_jsxs(_components.p,{children:[`Orbit’s pages: `,_jsx(_components.code,{children:`Dashboard`}),`, `,_jsx(_components.code,{children:`Projects/Index`}),`, `,_jsx(_components.code,{children:`Projects/Show`}),` (the main project workspace — filter bar plus the List/Board/Calendar switcher), `,_jsx(_components.code,{children:`Issues/Show`}),` (a single issue’s detail page), `,_jsx(_components.code,{children:`Settings/Index`}),` (see `,_jsx(_components.a,{href:`/concepts/settings`,children:`Settings`}),`), and `,_jsx(_components.code,{children:`Auth/Login`}),` / `,_jsx(_components.code,{children:`Auth/Register`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`layouts`,children:`Layouts`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`GuestLayout`}),` wraps the unauthenticated auth pages. `,_jsx(_components.code,{children:`MainLayout`}),` wraps everything else — sidebar, top navigation, and the current project/view context passed down to child pages.`]}),`\n`,_jsx(Heading,{level:`2`,id:`components-atomic-design`,children:`Components: atomic design`}),`\n`,_jsxs(_components.p,{children:[`Components are organized by composability, each in its own folder with a colocated test file (`,_jsx(_components.code,{children:`Button/Button.tsx`}),`, `,_jsx(_components.code,{children:`Button/Button.test.tsx`}),`):`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Atoms`}),` — the smallest building blocks: `,_jsx(_components.code,{children:`Button`}),`, `,_jsx(_components.code,{children:`Input`}),`, `,_jsx(_components.code,{children:`Badge`}),`, `,_jsx(_components.code,{children:`Avatar`}),`, `,_jsx(_components.code,{children:`Icon`}),`, and so on`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Molecules`}),` — small combinations of atoms: `,_jsx(_components.code,{children:`CommentForm`}),`, `,_jsx(_components.code,{children:`FilterDropdown`}),`, `,_jsx(_components.code,{children:`ProjectCard`}),`, `,_jsx(_components.code,{children:`NotificationItem`}),`, `,_jsx(_components.code,{children:`Breadcrumb`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Organisms`}),` — larger, feature-level components: `,_jsx(_components.code,{children:`IssueBoard`}),`, `,_jsx(_components.code,{children:`IssueTable`}),`, `,_jsx(_components.code,{children:`Sidebar`}),`, `,_jsx(_components.code,{children:`NewIssueModal`}),`, `,_jsx(_components.code,{children:`DashboardVisuals`}),`, `,_jsx(_components.code,{children:`SettingsSidebar`})]}),`\n`]}),`\n`,_jsx(_components.p,{children:`The composition rule is one-directional: organisms use molecules, molecules use atoms — never the reverse.`}),`\n`,_jsx(Heading,{level:`2`,id:`shared-state-and-logic`,children:`Shared state and logic`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Context`}),` (`,_jsx(_components.code,{children:`resources/js/context/`}),`) — `,_jsx(_components.code,{children:`AlertContext`}),` for toast messages (including flash messages from a redirect), `,_jsx(_components.code,{children:`ModalContext`}),` for orchestrating whichever modal is currently open, `,_jsx(_components.code,{children:`ShortcutContext`}),` for keyboard shortcuts, `,_jsx(_components.code,{children:`ThemeContext`}),` and `,_jsx(_components.code,{children:`AccentContext`}),` for the `,_jsx(_components.a,{href:`/guides/appearance`,children:`theme and accent color`}),`, both mounted at the root of `,_jsx(_components.code,{children:`app.tsx`}),` so they’re available everywhere`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Hooks`}),` (`,_jsx(_components.code,{children:`resources/js/hooks/`}),`) — `,_jsx(_components.code,{children:`useSavedFilters`}),` wraps saved-filter CRUD and applying a filter’s query params; `,_jsx(_components.code,{children:`useTableResizing`}),` handles resizable columns in the List view`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Types`}),` (`,_jsx(_components.code,{children:`resources/js/types/`}),`) — shared domain types (`,_jsx(_components.code,{children:`Issues.ts`}),`, `,_jsx(_components.code,{children:`Projects.ts`}),`, `,_jsx(_components.code,{children:`Users.ts`}),`, `,_jsx(_components.code,{children:`Notification.ts`}),`) and shared page-prop types`]}),`\n`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Some fields in `,_jsx(_components.code,{children:`types/Issues.ts`}),` (like `,_jsx(_components.code,{children:`milestone`}),`, `,_jsx(_components.code,{children:`sprint`}),`, or `,_jsx(_components.code,{children:`attachments_count`}),`) aren’t backed by any database column — they’re speculative additions to the type that don’t reflect a real, working feature. Don’t take the presence of a TypeScript field as confirmation a feature exists; check the `,_jsx(_components.code,{children:`issues`}),` table and `,_jsx(_components.code,{children:`IssueController`}),` before documenting or relying on it.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`styling`,children:`Styling`}),`\n`,_jsxs(_components.p,{children:[`Tailwind CSS, with `,_jsx(_components.code,{children:`class-variance-authority`}),` for component variants and a `,_jsx(_components.code,{children:`cn()`}),` helper (`,_jsx(_components.code,{children:`clsx`}),` + `,_jsx(_components.code,{children:`tailwind-merge`}),`) for combining classes. Colors come from CSS custom properties (`,_jsx(_components.code,{children:`--bg-color`}),`, `,_jsx(_components.code,{children:`--accent-color`}),`, `,_jsx(_components.code,{children:`--border-color`}),`, and so on) consumed as Tailwind arbitrary values like `,_jsx(_components.code,{children:`bg-[var(--bg-color)]`}),`, rather than Tailwind’s built-in color palette — see `,_jsx(_components.a,{href:`/guides/appearance`,children:`Appearance`}),` for the full token list and how Light/Dark/System theme switching works.`]}),`\n`,_jsx(Heading,{level:`2`,id:`path-alias`,children:`Path alias`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`@/`}),` resolves to `,_jsx(_components.code,{children:`resources/js/`}),` (configured in both `,_jsx(_components.code,{children:`tsconfig.json`}),` and the Vite config), so imports read as `,_jsx(_components.code,{children:`@/Components/Atoms/Button`}),` rather than long relative paths.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Frontend architecture","description":"Inertia pages, atomic-design components, and where shared logic lives","href":"/architecture/frontend-architecture"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Pages","slug":"pages","depth":2,"children":[]},{"title":"Layouts","slug":"layouts","depth":2,"children":[]},{"title":"Components: atomic design","slug":"components-atomic-design","depth":2,"children":[]},{"title":"Shared state and logic","slug":"shared-state-and-logic","depth":2,"children":[]},{"title":"Styling","slug":"styling","depth":2,"children":[]},{"title":"Path alias","slug":"path-alias","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"orbitdev","siteName":"Orbit","title":"Frontend architecture - Orbit","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-08-17T15:46:22.508Z","gitLastModified":"2026-08-17T15:46:01.000Z","originalFileLocation":"architecture/frontend-architecture.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Inertia pages, atomic-design components, and where shared logic lives\">\u003cmeta data-mint-head name=\"application-name\" content=\"Orbit\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/orbitdev/4rzSUglfsAI775a6/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/orbitdev/4rzSUglfsAI775a6/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/orbitdev/4rzSUglfsAI775a6/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/orbitdev/4rzSUglfsAI775a6/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/orbitdev/4rzSUglfsAI775a6/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/orbitdev/4rzSUglfsAI775a6/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/orbitdev/4rzSUglfsAI775a6/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/orbitdev/4rzSUglfsAI775a6/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/orbitdev/4rzSUglfsAI775a6/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Frontend architecture - Orbit\">\u003cmeta data-mint-head property=\"og:description\" content=\"Inertia pages, atomic-design components, and where shared logic lives\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Orbit\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.orbit-dev.app/architecture/frontend-architecture\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://orbitdev.mintlify.app/_mintlify/api/og/v2?division=Architecture\u0026amp;title=Frontend+architecture\u0026amp;description=Inertia+pages%2C+atomic-design+components%2C+and+where+shared+logic+lives\u0026amp;theme=434ed9dc0d6961afc844d8a3\u0026amp;signature=0ed31f8d3e599db4484d067dd5b9cc84feafe150af4bc3c77a9944ad8d87ac83\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Frontend architecture - Orbit\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Inertia pages, atomic-design components, and where shared logic lives\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://orbitdev.mintlify.app/_mintlify/api/og/v2?division=Architecture\u0026amp;title=Frontend+architecture\u0026amp;description=Inertia+pages%2C+atomic-design+components%2C+and+where+shared+logic+lives\u0026amp;theme=434ed9dc0d6961afc844d8a3\u0026amp;signature=0ed31f8d3e599db4484d067dd5b9cc84feafe150af4bc3c77a9944ad8d87ac83\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/orbitdev/4rzSUglfsAI775a6/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Orbit\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#8844DA\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.orbit-dev.app/architecture/frontend-architecture\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/architecture/frontend-architecture.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.orbit-dev.app/#organization\",\"name\":\"Orbit\",\"url\":\"https://docs.orbit-dev.app\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/orbitdev/RavC4algsRMlwGCe/logo/logo.png?fit=max\u0026auto=format\u0026n=RavC4algsRMlwGCe\u0026q=85\u0026s=ac954893e8902e9a3843245b5916ebe2\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.orbit-dev.app#website\",\"name\":\"Orbit\",\"url\":\"https://docs.orbit-dev.app\",\"publisher\":{\"@id\":\"https://docs.orbit-dev.app/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.orbit-dev.app/architecture/frontend-architecture#webpage\",\"url\":\"https://docs.orbit-dev.app/architecture/frontend-architecture\",\"name\":\"Frontend architecture\",\"description\":\"Inertia pages, atomic-design components, and where shared logic lives\",\"dateModified\":\"2026-08-17T15:46:01.000Z\",\"isPartOf\":{\"@id\":\"https://docs.orbit-dev.app#website\"},\"breadcrumb\":{\"@id\":\"https://docs.orbit-dev.app/architecture/frontend-architecture#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.orbit-dev.app/architecture/frontend-architecture#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Architecture\",\"item\":\"https://docs.orbit-dev.app/architecture/tech-stack\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Frontend architecture\",\"item\":\"https://docs.orbit-dev.app/architecture/frontend-architecture\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.orbit-dev.app/architecture/frontend-architecture#article\",\"headline\":\"Frontend architecture\",\"name\":\"Frontend architecture\",\"description\":\"Inertia pages, atomic-design components, and where shared logic lives\",\"url\":\"https://docs.orbit-dev.app/architecture/frontend-architecture\",\"mainEntityOfPage\":{\"@id\":\"https://docs.orbit-dev.app/architecture/frontend-architecture#webpage\"},\"dateModified\":\"2026-08-17T15:46:01.000Z\",\"publisher\":{\"@id\":\"https://docs.orbit-dev.app/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.orbit-dev.app#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Orbit\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Orbit","nav":{"global":null,"groups":[{"group":"Get Started","icon":"home-alt","tag":"START HERE","pages":[{"title":"Introduction","href":"/index"},{"title":"Quickstart","href":"/quickstart"}]},{"group":"Core Concepts","pages":[{"title":"Account","href":"/concepts/account"},{"title":"Settings","href":"/concepts/settings"},{"title":"Projects","href":"/concepts/projects"},{"title":"Project labels","href":"/concepts/labels"},{"title":"Issue types","href":"/concepts/issue-types"},{"title":"Issues","href":"/concepts/issues"},{"title":"Comments","href":"/concepts/comments"},{"title":"Dashboard","href":"/concepts/dashboard"},{"title":"Activity log","href":"/concepts/activity-log"},{"title":"Notifications","href":"/concepts/notifications"},{"title":"Saved Filters","href":"/concepts/saved-filters"}]},{"group":"Guides","pages":[{"title":"List, Board, Calendar, and Activity views","href":"/guides/views"},{"title":"Configure workflows","href":"/guides/workflows"},{"title":"Filtering and search","href":"/guides/filtering-and-search"},{"title":"Roles and permissions","href":"/guides/roles-and-permissions"},{"title":"Manage members and roles","href":"/guides/members-and-roles"},{"title":"Integrations","href":"/guides/integrations"},{"title":"Import from Jira","href":"/guides/jira-import"},{"title":"GitHub integration","href":"/guides/github-integration"},{"title":"Automation","href":"/guides/automation"},{"title":"Onboarding","href":"/guides/onboarding"},{"title":"Appearance","href":"/guides/appearance"},{"title":"Keyboard shortcuts","href":"/guides/keyboard-shortcuts"},{"title":"Writing issue descriptions","href":"/guides/rich-text-editing"}]},{"group":"Architecture","pages":[{"title":"Tech stack","href":"/architecture/tech-stack"},{"title":"Backend architecture","description":"Controller → Service → Repository, and how the layers divide responsibility","href":"/architecture/backend-architecture"},{"title":"Frontend architecture","href":"/architecture/frontend-architecture"},{"title":"Database schema","description":"Tables, relationships, and enums behind Orbit's core concepts","href":"/architecture/database-schema"},{"title":"Testing","href":"/architecture/testing"},{"title":"Contributing","href":"/architecture/contributing"}]},{"group":"Deployment","pages":[{"title":"Configuration","href":"/deployment/configuration"},{"title":"Docker","href":"/deployment/docker"},{"title":"Production deployment","href":"/deployment/production"}]},{"group":"Reference","icon":"question-circle","pages":[{"title":"Glossary","href":"/reference/glossary"},{"title":"Known limitations","href":"/reference/known-limitations"},{"title":"FAQ and troubleshooting","href":"/reference/faq"}]}]},"title":"Frontend architecture - Orbit","buildId":"dpl_2oYXwqkEXirXBPk8wV1FtM5USFWi","deploymentId":"dpl_2oYXwqkEXirXBPk8wV1FtM5USFWi","dynamics":[],"chunks":[]}