khoj-ai on GitHub

khoj-ai/khoj

Reviewed against Rams quality heuristics: accessibility, color, typography, spacing, components, motion, UX, and craft.

30 files reviewed·July 25, 2026

View on GitHub

Elevated

Design risk in this codebase.

2issues
Critical & Serious

Top fix

Make sign-up and 'New' buttons focusable and operable via keyboard

See the fix

Verdict

Core actions look intentional but only work for pointer users, a hard blocker for any keyboard-first flow. Sidebar icons mix libraries and undercut the otherwise coherent visual language.

Files Rams reviewed

src/interface/web/app/components/allConversations/sidePanel.module.css

src/interface/web/app/components/appSidebar/appSidebar.tsx

src/interface/web/app/components/chatHistory/chatHistory.module.css

src/interface/web/app/components/chatMessage/FileContentSnippet.tsx

src/interface/web/app/components/chatMessage/chatMessage.module.css

src/interface/web/app/components/deprecationBanner.tsx

src/interface/web/app/components/excalidraw/excalidrawWrapper.tsx

src/interface/web/app/components/loading/loading.tsx

src/interface/web/app/components/loginPrompt/loginPopup.tsx

src/interface/web/app/components/loginPrompt/loginPrompt.module.css

src/interface/web/app/components/logo/fileLogo.tsx

src/interface/web/app/components/mermaid/mermaid.tsx

src/interface/web/app/components/navMenu/navMenu.module.css

src/interface/web/app/components/navMenu/navMenu.tsx

src/interface/web/app/components/profileCard/profileCard.tsx

src/interface/web/app/components/shareLink/shareLink.tsx

src/interface/web/app/components/suggestions/suggestionCard.tsx

src/interface/web/app/components/userMemory/userMemory.tsx

src/interface/web/app/agents/layout.tsx

src/interface/web/app/automations/layout.tsx

src/interface/web/app/chat/layout.tsx

src/interface/web/app/layout.tsx

src/interface/web/app/settings/layout.tsx

src/interface/web/app/share/chat/layout.tsx

src/interface/web/app/share/chat/page.tsx

src/interface/web/app/components/agentCard/agentCard.module.css

src/interface/web/app/components/chatInputArea/chatInputArea.module.css

src/interface/web/app/components/chatWoot/ChatwootWidget.tsx

src/interface/web/app/components/excalidraw/excalidraw.tsx

src/interface/web/app/components/loginPrompt/GoogleSignIn.tsx

97/100

Accessibility

1 critical
AccessibilityCritical

src/interface/web/app/components/appSidebar/appSidebar.tsx:147

"Sign up to get started" and "New" actions are unreachable by keyboard

Both `SidebarMenuButton` items use `asChild` with a plain `<div>` as the rendered element: the sign-up prompt ("Sign up to get started", line 147) and the primary chat action ("New", line 161). The `onClick` handlers land on a non-interactive div, so neither element receives a tab stop, a button role, or Enter/Space activation.

Why it matters

Keyboard and screen reader users cannot start a new chat or sign up at all, the two most frequent entry points in this sidebar, which locks a whole user segment out of the core action.

Fix

Render the asChild target as a real button element so native focus and keyboard activation come for free.

<SidebarMenuButton asChild variant={"default"} onClick={() => setShowLoginPrompt(true)}>
    <div>
        <UserPlusIcon />
        <span>Sign up to get started</span>
    </div>
</SidebarMenuButton>
<SidebarMenuButton asChild variant={"default"} onClick={() => setShowLoginPrompt(true)}>
    <button type="button">
        <UserPlusIcon />
        <span>Sign up to get started</span>
    </button>
</SidebarMenuButton>
98/100

Components

1 serious
ComponentsSerious

src/interface/web/app/components/appSidebar/appSidebar.tsx:21

Mixed icon libraries in the sidebar break visual consistency

The sidebar imports `Plus`, `Gear`, `HouseSimple` from `@phosphor-icons/react` but `UserPlusIcon` from `lucide-react`. Phosphor icons in this codebase use a consistent stroke weight and rounded terminal style; lucide's default stroke and corner geometry differ, so the "Sign up to get started" icon reads at a different weight than every other icon in the same menu.

Why it matters

A single panel with two icon styles reads as unfinished and undermines the perceived polish of the product on the very first screen users see.

Fix

Use one icon library consistently within a shared component tree; swap the lucide icon for its Phosphor equivalent.

import { Plus, Gear, HouseSimple } from "@phosphor-icons/react";
...
import { UserPlusIcon } from "lucide-react";
import { Plus, Gear, HouseSimple, UserPlus } from "@phosphor-icons/react";
// remove the lucide-react import and use <UserPlus /> in its place

Typography

No issues found

Color

No issues found

Spacing

No issues found

Motion

No issues found

UX

No issues found

Craft

No issues found

Working well

  • The inline blocking script that applies the `dark` class before hydration is the correct way to prevent a flash of incorrect theme on load, and pairing it with `suppressHydrationWarning` avoids a React mismatch warning.
  • Setting `lang="en"` on the html root is exactly right for screen readers and pronunciation, and using next/font variables for both noto_sans and noto_sans_arabic keeps font loading self-hosted and swap-safe.
  • Splitting the collapsed vs expanded logo into two SidebarMenuButton branches (KhojLogoType vs KhojLogo) is a clean way to keep the header usable at both sidebar widths.
  • Escape-to-collapse plus dispatching a resize event so Excalidraw recalculates its canvas is a thoughtful touch most implementations miss.

Scored July 25, 2026 with Rams Engine v0.0.3 · Engine changelog
First scored July 9, 2026: 59/100. This rescore on v0.0.3: 59/100.

This page is an automated design review of khoj-ai/khoj’s UI code: 30 files read against 309 versioned rules covering accessibility, color, typography, spacing, components, UX, motion, and craft. The score is out of 100; confirmed criticals cap it — one at 59, two at 49, three or more at 39.

More design scores

Score your own repo.

Free on public repos, no account. The same engine that scored this page reads your UI code and mints a score page like this one.

Public repos only. The full engine reviews the UI code and mints a public score page — we email you the link too. Already-scored repos open instantly.

Or get a design review on every pull requestInstall Rams