Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Want an AI model or a coding agent in your terminal? This list has coding agents such as Claude Code, Codex CLI, and Aider, tools that run models on your own machine such as Ollama and llama.cpp, and small helpers that send text to a model. Each row shows the type, language, license, and platforms, with the most starred tools first.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains CLI apps in the Communication category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Need to query a database or run a migration without leaving the terminal? This list has clients with autocomplete such as pgcli, mycli, and litecli, engines you can run from a prompt such as DuckDB and SQLite, and migration tools such as dbmate, Atlas, and Goose. Each row shows the type, language, license, and platforms.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Building software and want better tools in your terminal? This is the largest category in the directory. It covers runtimes and toolchains such as Go, Deno, and Bun, editors such as Neovim and Emacs, package managers such as uv, and coding agents. Rows are sorted by GitHub stars, so the most starred tools come first.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Deploying an app or looking after a server from the terminal? This list covers infrastructure tools such as Terraform and Ansible, container and Kubernetes tools such as lazydocker, dive, and K9s, and the official CLIs for GitHub, GitLab, Fly.io, Railway, Supabase, and Stripe. Each row shows the type, language, license, and platforms.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Need to find, move, or back up files faster than a file manager allows? This list has search tools such as ripgrep and fd, sync and transfer tools such as rclone and croc, backup tools such as restic, and terminal file managers such as Yazi and Midnight Commander. It also covers duplicate finders and disk usage tools such as fclones and ncdu.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains CLI apps in the Games and fun category.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { ComponentType } from "react";
import Intro0 from "./development/intro.mdx";
import Intro1 from "./devops/intro.mdx";
import Intro2 from "./files/intro.mdx";
import Intro3 from "./text/intro.mdx";
import Intro4 from "./networking/intro.mdx";
import Intro5 from "./security/intro.mdx";
import Intro6 from "./monitoring/intro.mdx";
import Intro7 from "./databases/intro.mdx";
import Intro8 from "./media-graphics/intro.mdx";
import Intro9 from "./productivity/intro.mdx";
import Intro10 from "./communication/intro.mdx";
import Intro11 from "./games-fun/intro.mdx";
import Intro12 from "./terminal-ui/intro.mdx";
import Intro13 from "./ai/intro.mdx";

export const categoryIntros: Record<string, ComponentType> = {
"development": Intro0,
"devops": Intro1,
"files": Intro2,
"text": Intro3,
"networking": Intro4,
"security": Intro5,
"monitoring": Intro6,
"databases": Intro7,
"media-graphics": Intro8,
"productivity": Intro9,
"communication": Intro10,
"games-fun": Intro11,
"terminal-ui": Intro12,
"ai": Intro13,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Want to convert, download, or play media without opening a desktop app? This list has converters such as ffmpeg and ImageMagick, downloaders such as yt-dlp and gallery-dl, and players such as mpv, cmus, and ncspot. A few tools show images right in the terminal, such as Chafa and viu.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Trying to see what is using your CPU, disk, or network? This list has process monitors such as btop, Glances, and bottom, disk usage tools such as duf, dust, and ncdu, and network tools such as gping and bandwhich. It also has benchmarking and log tools such as hyperfine and lnav.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Debugging a connection or testing an API from the terminal? This list has HTTP clients such as curl, HTTPie, and Hurl, DNS tools such as doggo and dnsx, and tunnel and VPN tools such as frp and Tailscale. For tracing and packet capture there are MTR and tcpdump. To check DNS records in the browser, use our [DNS lookup](/dns-lookup).
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Spend most of your day in a terminal and want it to go faster? This list has finders and jumpers such as fzf and zoxide, session managers such as tmux and Zellij, task runners such as just, and dotfile managers such as chezmoi. It also has calendar, time tracking, and password tools such as calcurse, Timewarrior, and password-store.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Want to check your code and servers for problems before someone else does? This list has secret scanners such as Gitleaks and TruffleHog, vulnerability scanners such as Trivy and Nuclei, and encryption tools such as age and GnuPG. For certificates there are mkcert, acme.sh, and step CLI, and for passwords there are KeePassXC CLI and password-store.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Setting up a terminal you will enjoy using? This list has terminal emulators such as Ghostty, Alacritty, and Warp, shells such as Zsh, Bash, and PowerShell, and prompts and themes such as Starship and Powerlevel10k. It also has full-screen terminal apps such as lazygit, lazydocker, and Yazi. For Ghostty, Warp, and other apps, see our [keyboard shortcuts](/keyboard-shortcuts).
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Editing, searching, or converting text in the terminal? This list has editors such as Neovim, Helix, Vim, and micro, JSON tools such as jq and fx, and diff viewers such as delta and Difftastic. For documents there are Pandoc to convert formats and Glow and mdcat to read Markdown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { registryLayout } from "@/lib/registry-layout";

const registry = registryLayout("/cli-apps/categories/[category]");
export const generateMetadata = registry.generateMetadata;
export function generateStaticParams() { return []; }
export const revalidate = false;
export default registry.Layout;
29 changes: 29 additions & 0 deletions app/(site)/(directories)/cli-apps/categories/[category]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { notFound } from "next/navigation";
import { getRequiredDirectoryPage } from "@/lib/directory-pages";
import { getAppCategoryLinks } from "@/lib/app-categories";
import { appCategoryStaticParams, selectCategoryApps, MIN_CATEGORY_APPS } from "@/lib/app-category-model";
import { getTerminalApps, terminalAppTypeLabels } from "@/lib/terminal-apps";
import { AppCategoryPage } from "@/app/ui/directories/app-category-page";
import { categoryIntros } from "./content";

export const revalidate = false;
export async function generateStaticParams() {
return appCategoryStaticParams(await getAppCategoryLinks("cli-apps"));
}

export default async function CategoryPage({ params }: { params: Promise<{ category: string }> }) {
const { category } = await params;
const directoryPage = await getRequiredDirectoryPage(`cli-apps/categories/${category}`);
const categories = await getAppCategoryLinks("cli-apps");
if (!categories.some(entry => entry.slug === category)) notFound();
const Intro = categoryIntros[category];
if (!Intro) throw new Error(`Missing CLI category intro: ${category}`);
const apps = selectCategoryApps(await getTerminalApps(), category, app => app.categories, app => app.stars ?? 0);
if (apps.length < MIN_CATEGORY_APPS) notFound();
return <AppCategoryPage directory="cli-apps" category={category} directoryPage={directoryPage}
intro={<Intro />} categories={categories} apps={apps.map(app => ({
name: app.name, summary: app.summary, href: app.repository_url || app.website_url,
facts: [terminalAppTypeLabels.get(app.primary_type) ?? app.primary_type, app.language || "Language unknown",
app.license || "License unknown", app.platforms.length ? app.platforms.join(", ") : "Platforms unknown"].join(" · "),
}))} />;
}
2 changes: 1 addition & 1 deletion app/(site)/(directories)/cli-apps/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import "../../../ui/directories/directory.css";
import { registryLayout } from "@/lib/registry-layout";

const registry = registryLayout("/cli-apps");
const registry = registryLayout("/cli-apps", { structuredData: "page" });
export const generateMetadata = registry.generateMetadata;
export const revalidate = false;
export default registry.Layout;
7 changes: 7 additions & 0 deletions app/(site)/(directories)/cli-apps/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { AppCategoryLinks } from "@/app/ui/directories/app-category-links";
import { getAppCategoryLinks } from "@/lib/app-categories";
import { RegistryStructuredData } from "@/lib/registry-layout";
import { getRequiredDirectoryPage } from "@/lib/directory-pages";
import { getBreadcrumbs } from "@/lib/breadcrumbs";
import { DirectoryPageTitle } from "@/app/ui/directories/directory-page-content";
Expand Down Expand Up @@ -131,6 +134,8 @@ export default async function CliAppsPage() {
/>
);

const categoryLinks = await getAppCategoryLinks("cli-apps");

return (
<DirectoryQueryProvider route="/cli-apps">
<AppShell
Expand All @@ -139,6 +144,7 @@ export default async function CliAppsPage() {
sidebar={sidebar}
sidebarLabel="Terminal app filters"
>
<RegistryStructuredData path="/cli-apps" />
<EntryHero art={siteSpotCliAppsArt}>
<PageHeader breadcrumbs={await getBreadcrumbs("cli-apps")}>
<h1><DirectoryTitleIcon iconKey={directoryPage.card_icon_key} />{" "}<DirectoryPageTitle title={directoryPage.title} /></h1>
Expand All @@ -149,6 +155,7 @@ export default async function CliAppsPage() {
<PageCanvas as="div" flow className="directory-results">
<CliAppResults firstPage={defaultApps} total={apps.length} categoryLabels={categoryLabels} emptyVisual={<Doodle svg={siteDoodleStarArt} />} />
<HiddenDetails prefix="cli-app" items={defaultApps.map((app) => ({ slug: app.slug, name: app.name, body: <CliAppDetailsBody app={app} /> }))} />
<AppCategoryLinks categories={categoryLinks} />
<article className={`${proseClassName} ${proseSectionFlowClassName}`}>
<section>
<Types />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the ai & ml category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the automation category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the bookmarks & read-it-later category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the business & commerce category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the calendars & contacts category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the communication category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the communities & social category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the content & publishing category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the dashboards category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the databases category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the design & creative category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the developer tools category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the documents & pdfs category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the e-books & libraries category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the email & newsletters category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the file sharing & sync category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the finance & budgeting category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the forms, polls & events category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the games category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the health & fitness category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the home automation & iot category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the identity & access category.
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import type { ComponentType } from "react";
import Intro0 from "./ai-ml/intro.mdx";
import Intro1 from "./automation/intro.mdx";
import Intro2 from "./bookmarks-read-it-later/intro.mdx";
import Intro3 from "./business-commerce/intro.mdx";
import Intro4 from "./calendars-contacts/intro.mdx";
import Intro5 from "./communication/intro.mdx";
import Intro6 from "./communities-social/intro.mdx";
import Intro7 from "./content-publishing/intro.mdx";
import Intro8 from "./dashboards/intro.mdx";
import Intro9 from "./databases/intro.mdx";
import Intro10 from "./design-creative/intro.mdx";
import Intro11 from "./developer-tools/intro.mdx";
import Intro12 from "./documents-pdfs/intro.mdx";
import Intro13 from "./ebooks-libraries/intro.mdx";
import Intro14 from "./email-newsletters/intro.mdx";
import Intro15 from "./file-sharing-sync/intro.mdx";
import Intro16 from "./finance-budgeting/intro.mdx";
import Intro17 from "./forms-polls-events/intro.mdx";
import Intro18 from "./games/intro.mdx";
import Intro19 from "./health-fitness/intro.mdx";
import Intro20 from "./home-automation-iot/intro.mdx";
import Intro21 from "./identity-access/intro.mdx";
import Intro22 from "./knowledge-notes/intro.mdx";
import Intro23 from "./learning-courses/intro.mdx";
import Intro24 from "./maps-travel/intro.mdx";
import Intro25 from "./media-device-control/intro.mdx";
import Intro26 from "./media-servers/intro.mdx";
import Intro27 from "./monitoring-status/intro.mdx";
import Intro28 from "./music-audio/intro.mdx";
import Intro29 from "./networking-dns/intro.mdx";
import Intro30 from "./password-managers/intro.mdx";
import Intro31 from "./photos-galleries/intro.mdx";
import Intro32 from "./project-task-management/intro.mdx";
import Intro33 from "./recipes-food/intro.mdx";
import Intro34 from "./remote-access/intro.mdx";
import Intro35 from "./search/intro.mdx";
import Intro36 from "./security-privacy/intro.mdx";
import Intro37 from "./storage-backup/intro.mdx";
import Intro38 from "./system-admin-hosting/intro.mdx";
import Intro39 from "./time-tracking/intro.mdx";
import Intro40 from "./video-conferencing/intro.mdx";
import Intro41 from "./wikis/intro.mdx";

export const categoryIntros: Record<string, ComponentType> = {
"ai-ml": Intro0,
"automation": Intro1,
"bookmarks-read-it-later": Intro2,
"business-commerce": Intro3,
"calendars-contacts": Intro4,
"communication": Intro5,
"communities-social": Intro6,
"content-publishing": Intro7,
"dashboards": Intro8,
"databases": Intro9,
"design-creative": Intro10,
"developer-tools": Intro11,
"documents-pdfs": Intro12,
"ebooks-libraries": Intro13,
"email-newsletters": Intro14,
"file-sharing-sync": Intro15,
"finance-budgeting": Intro16,
"forms-polls-events": Intro17,
"games": Intro18,
"health-fitness": Intro19,
"home-automation-iot": Intro20,
"identity-access": Intro21,
"knowledge-notes": Intro22,
"learning-courses": Intro23,
"maps-travel": Intro24,
"media-device-control": Intro25,
"media-servers": Intro26,
"monitoring-status": Intro27,
"music-audio": Intro28,
"networking-dns": Intro29,
"password-managers": Intro30,
"photos-galleries": Intro31,
"project-task-management": Intro32,
"recipes-food": Intro33,
"remote-access": Intro34,
"search": Intro35,
"security-privacy": Intro36,
"storage-backup": Intro37,
"system-admin-hosting": Intro38,
"time-tracking": Intro39,
"video-conferencing": Intro40,
"wikis": Intro41,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the knowledge & notes category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the learning & courses category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the maps & travel category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the media device control category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the media servers category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the monitoring & status category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the music & audio category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the networking & dns category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the password managers category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the photos & galleries category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the project & task management category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the recipes & food category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the remote access category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the search category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the security & privacy category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the storage & backup category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the system admin & hosting category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the time tracking category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the video & conferencing category.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This list contains self-hosted apps in the wikis category.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { registryLayout } from "@/lib/registry-layout";

const registry = registryLayout("/self-host-apps/categories/[category]");
export const generateMetadata = registry.generateMetadata;
export function generateStaticParams() { return []; }
export const revalidate = false;
export default registry.Layout;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { notFound } from "next/navigation";
import { getRequiredDirectoryPage } from "@/lib/directory-pages";
import { getAppCategoryLinks, getSelfHostCategoryApps } from "@/lib/app-categories";
import { appCategoryStaticParams, MIN_CATEGORY_APPS } from "@/lib/app-category-model";
import { AppCategoryPage } from "@/app/ui/directories/app-category-page";
import { categoryIntros } from "./content";

export const revalidate = false;
export async function generateStaticParams() {
return appCategoryStaticParams(await getAppCategoryLinks("self-host-apps"));
}

export default async function CategoryPage({ params }: { params: Promise<{ category: string }> }) {
const { category } = await params;
const directoryPage = await getRequiredDirectoryPage(`self-host-apps/categories/${category}`);
const categories = await getAppCategoryLinks("self-host-apps");
if (!categories.some(entry => entry.slug === category)) notFound();
const Intro = categoryIntros[category];
if (!Intro) throw new Error(`Missing self-host category intro: ${category}`);
const apps = await getSelfHostCategoryApps(category);
if (apps.length < MIN_CATEGORY_APPS) notFound();
return <AppCategoryPage directory="self-host-apps" category={category} directoryPage={directoryPage}
intro={<Intro />} categories={categories} apps={apps.map(app => ({
name: app.name, summary: app.summary, href: app.href,
facts: [app.license || app.source_model.replaceAll("_", " "), app.maintenance_status,
`Docker: ${app.docker_support.replaceAll("_", " ")}`,
...(app.ram_min_mb !== null ? [`Minimum RAM: ${app.ram_min_mb} MB`] : [])].join(" · "),
}))} />;
}
2 changes: 1 addition & 1 deletion app/(site)/(directories)/self-host-apps/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import "../../../ui/directories/directory.css";
import { registryLayout } from "@/lib/registry-layout";

const registry = registryLayout("/self-host-apps");
const registry = registryLayout("/self-host-apps", { structuredData: "page" });
export const generateMetadata = registry.generateMetadata;
export const revalidate = false;
export default registry.Layout;
Loading
Loading