by Octavia

Homarr is a sleek, customizable dashboard for self-hosted servers that centralizes app access, integrates with popular services like Plex, Sonarr, and Pi-hole, and offers drag-and-drop management with no YAML required.
Homarr is a full-stack Next.js self-hosted dashboard for managing home-server applications. It exposes a board-based UI with drag-and-drop widgets, integrations with torrent clients, media servers, and arr-stack apps, backed by a tRPC API and Drizzle ORM SQLite database. The typical buyer is a backend/full-stack developer who wants to embed or extend this dashboard inside an existing Node.js/Next.js project.
src/ - Full Next.js application source: pages, components, server routes, tRPC routers, hooks, toolsdrizzle/ - SQL migration files and Drizzle ORM schema/meta snapshotsdrizzle/migrate/ - Migration runner (migrate.ts) for applying DB changescli/ - Node.js CLI for admin tasks (password reset, owner management)public/ - Static assets: locales (i18n JSON), icons, logos, PWA manifestsdata/ - Default board config JSON and app constantsscripts/ - Utility scripts for build/dev tasksdocs/ - Documentation images and assets.github/ - CI/CD workflows (Docker publish, stale bot, greetings).vscode/ - Editor launch/settings configsnext.config.js - Next.js configurationnext-i18next.config.js - i18n namespace configurationdrizzle.config.ts - Drizzle ORM connection/migration configtsconfig.json - TypeScript paths and compiler optionsvitest.config.ts - Unit test configurationturbo.json - Turborepo pipeline confignpm install next react react-dom
npm install @mantine/core @mantine/hooks @mantine/form @mantine/modals @mantine/notifications @mantine/next @mantine/dates @mantine/tiptap @mantine/prism
npm install @emotion/react @emotion/server
npm install @tabler/icons-react
npm install @tanstack/react-query @tanstack/react-query-devtools
npm install @t3-oss/env-nextjs
npm install @trpc/server @trpc/client @trpc/react-query @trpc/next
npm install next-auth
npm install next-i18next react-i18next i18next
npm install drizzle-orm better-sqlite3
npm install drizzle-kit
npm install @nivo/core @nivo/line
npm install @tiptap/extension-color @tiptap/extension-highlight @tiptap/extension-image
npm install @ctrl/deluge @ctrl/qbittorrent @ctrl/shared-torrent @ctrl/transmission
npm install @jellyfin/sdk
npm install zod
npm install -D typescript @types/react @types/node @types/better-sqlite3
Spin up an isolated sandbox and run it server-side — no local setup.
Tetrees AI Review of this version
This TypeScript cli / script completed archive review. Structure, dependency manifests, documentation, functional source, and common risk patterns were checked by the Tetrees verification pipeline; runtime phases are stated separately.
Deterministic AVCP artifact review
Pipeline avcp-2026-08-04.1 · SHA-256 d01487a745e59570…
This version-scoped review deterministically inspects the submitted archive for structure, dependencies, documentation, functional source, and common malicious or high-risk signals. Build and test phases are reported as passed only after an isolated sandbox audition. It is not a guarantee of perfect security.
Reviewed Aug 4, 2026
Push this product straight into your AI IDE, web builder or cloud IDE.
Connect Tetrees to a compatible AI IDE, list products you own, and request the verified ZIP without exposing seller upload controls.
No reviews yet.
Sign in to join the discussion
Loading discussion…
No native iOS/Android steps are required. If running in Docker (recommended), ensure /var/run/docker.sock is mounted or DOCKER_HOST/DOCKER_PORT env vars are set for Docker integration detection.
Copy source: Place the contents of source/ into your project root, or symlink src/, public/, drizzle/, data/ as needed.
TypeScript paths: Ensure tsconfig.json includes the ~ alias:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~/*": ["./src/*"]
}
}
}
Environment variables: Create .env (or .env.local) with:
# Required
NEXTAUTH_SECRET=your-secret-here
NEXTAUTH_URL=http://localhost:3000
# Database (SQLite default)
DATABASE_URL=./data/homarr.db
# Optional Docker integration
DOCKER_HOST=unix:///var/run/docker.sock
# Optional
AUTH_PROVIDER=credentials # or ldap, oidc
Run migrations: Before starting, apply DB schema:
npx ts-node drizzle/migrate/migrate.ts
# or if using the drizzle-kit approach:
npx drizzle-kit migrate
Start dev server:
npm run dev
# or
npx next dev
i18n: Locale JSON files live in public/locales/. next-i18next.config.js defines namespaces. Ensure next.config.js wraps with nextI18NextConfig.
BoardPage (default export from src/pages/board/index.tsx)import BoardPage, { getServerSideProps } from '~/pages/board/index';
// Props inferred from getServerSideProps
The main dashboard page component. Calls useInitConfig with the server-fetched board config and renders <BoardLayout> + <Dashboard>. Wire getServerSideProps to load the correct board for the authenticated user; it reads the default board name from user settings, fetches the config JSON, checks guest access, and injects isDockerEnabled.
getServerSideProps (from src/pages/board/index.tsx)export const getServerSideProps: (
context: GetServerSidePropsContext
) => Promise<{
props: {
config: FrontendConfig;
primaryColor: string;
secondaryColor: string;
primaryShade: number;
isDockerEnabled: boolean;
// ...i18n translations
};
}>
Server-side data loader for the board page. Authenticates the session, resolves the user's default board, fetches its config, enforces login/guest access policy via checkForSessionOrAskForLogin, and detects Docker availability from environment. Use this as the canonical SSR entry point when embedding the board.
BoardsPage (default export from src/pages/manage/boards/index.tsx)import BoardsPage, { getServerSideProps } from '~/pages/manage/boards/index';
Management UI for listing, creating, renaming, duplicating, and deleting boards. Uses api.boards.all.useQuery (tRPC) with server-side initial data from boardRouter. Requires an authenticated admin session. Mount under /manage/boards in your Next.js router.
MediaDisplay (from src/modules/common/index.ts)export * from './MediaDisplay';
// Re-exports the MediaDisplay component
import { MediaDisplay } from '~/modules/common';
Common module export for displaying media content in widgets. Use it in custom widget implementations that need to render images or media from integrated services.
Drop source/src/pages/board/index.tsx into your pages/ directory. The page fetches its own data server-side.
// pages/board/index.tsx (already provided in source)
// Just ensure your _app.tsx wraps with SessionProvider and tRPC:
import { SessionProvider } from 'next-auth/react';
import { api } from '~/utils/api';
import type { AppProps } from 'next/app';
function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
return (
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
);
}
export default api.withTRPC(MyApp);
// pages/custom-board.tsx
import { GetServerSidePropsContext, InferGetServerSidePropsType } from 'next';
import { getServerSideProps } from '~/pages/board/index';
import { useInitConfig } from '~/config/init';
export { getServerSideProps };
export default function CustomBoardPage({
config,
isDockerEnabled,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
useInitConfig(config);
return (
<div>
<p>Docker enabled: {String(isDockerEnabled)}</p>
<p>Board: {config.configProperties?.name}</p>
</div>
);
}
// pages/admin/index.tsx
// The management page renders a quick-actions grid for the logged-in user.
// Just re-export as Next.js page:
export { default, getServerSideProps } from '~/pages/manage/index';
To mount at a custom route, copy the file and adjust imports. The page uses useSession and useTranslation internally; ensure SessionProvider and appWithTranslation wrappers are present in _app.tsx.
// scripts/migrate.ts
import { migrate } from '~/drizzle/migrate/migrate';
// Or invoke directly:
// npx ts-node drizzle/migrate/migrate.ts
async function main() {
await migrate();
console.log('Migrations applied');
}
main();
src/ - Contains all application logic: pages/ (Next.js routes), components/ (UI), server/ (tRPC routers, auth, DB queries), tools/ (server/client utilities), hooks/, config/, modules/, types/, utils/.drizzle/ - SQL migration files generated by Drizzle Kit; meta/ holds schema snapshots; migrate/migrate.ts is the migration runner.cli/ - Standalone Node.js CLI (cli.js) with commands for reset-password and reset-owner-password; runs independently of Next.js.public/ - Static files served by Next.js: locales/ (i18n JSON per language/namespace), imgs/ (logos, icons, favicons, PWA assets).data/ - default.json is the fallback board configuration; constants.ts exports app-wide constants.scripts/ - Helper scripts for development/build automation.docs/ - PNG/image assets used in README documentation only..github/ - GitHub Actions workflows for Docker image builds, stale issue management, contributor greetings..vscode/ - VS Code debugger launch config and editor settings for the monorepo.next.config.js - Webpack customizations, image domains, environment variable exposure.drizzle.config.ts - Drizzle ORM dialect and migration folder configuration.tsconfig.json - Path aliases (~/*), strict mode, Next.js plugin.vitest.config.ts - Unit/integration test runner configuration.turbo.json - Turborepo task pipeline for build, lint, test.NEXTAUTH_SECRET: Auth will throw a hard error at startup; always set it even in development via .env.local.DATABASE_URL points to a path the process cannot write, Drizzle silently fails on migration; run chmod 664 on the DB file and parent directory.~ path alias not resolved: Add "paths": { "~/*": ["./src/*"] } to tsconfig.json and install tsconfig-paths if running scripts outside Next.js (ts-node -r tsconfig-paths/register).DOCKER_HOST, DOCKER_PORT, or /var/run/docker.sock; when running outside Docker, explicitly set DOCKER_HOST=unix:///var/run/docker.sock if a socket exists elsewhere.boardNamespaces); if a locale JSON file is missing under public/locales/<lang>/, next-i18next will silently fall back and keys will render raw. Copy all files from public/locales/en/ as a baseline.@mantine/next SSR emotion cache: Without wrapping _document.tsx with Mantine's createGetInitialProps, styles will flash on load; follow the Mantine SSR guide and use createStylesServer from @mantine/next.I have purchased the Homarr (homarr@0.16.0) source block. The source is in ./source/
and the integration guide is in ./source/USAGE.md.
My project is: [describe your existing Next.js / Node.js project and its structure].
Please integrate the Homarr dashboard into my project step by step:
1. Read USAGE.md and the file excerpts in source/src/pages/board/index.tsx,
source/src/pages/manage/boards/index.tsx, and source/src/modules/common/index.ts.
2. Install all dependencies listed in USAGE.md ## Required dependencies into my package.json.
3. Copy and wire the necessary files from source/src/ into my project, preserving the ~ path alias.
4. Set up the environment variables from USAGE.md ## Project setup section.
5. Wire NextAuth, tRPC (api.withTRPC), and next-i18next (appWithTranslation) in my _app.tsx.
6. Apply Drizzle migrations using source/drizzle/migrate/migrate.ts before the dev server starts.
7. Show me how to render BoardPage at /board and ManagementPage at /manage using the real
exports from source/ without inventing any new APIs.
8. Point out any conflicts with my existing code and suggest fixes.
Homarr is released under the MIT License. See source/LICENSE for the full text. The upstream project is maintained at github.com/ajnart/homarr (archived; active development continues at homarr-labs/homarr). This block packages version 0.16.0.
This product’s unique contribution is clean room implementation of valuable code block into AVCP compatible standard.
The full install guide and integration prompts unlock after purchase.
CRM, ERP, Admin & Internal Tools
Free