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
2 changes: 1 addition & 1 deletion content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ For an instance of your own, install LibreChat with the [Quick Start](/docs/quic

<Callout type="info" title="Looking for a desktop installer?">

LibreChat is a self-hosted web application, not a native Windows app or Linux AppImage. On Windows, use [Docker Desktop](/docs/local/docker) for the simplest local setup. For Linux desktops or servers, use [Docker](/docs/local/docker), [npm](/docs/local/npm), or a [remote hosting guide](/docs/remote).
LibreChat is a self-hosted web application, not a native Windows, macOS, or Linux desktop app. On Windows, use [Docker Desktop](/docs/local/docker) for the simplest local setup. On macOS, also use [Docker Desktop](/docs/local/docker); on Apple Silicon (M-series) Macs, read the Apple Silicon MongoDB note in the Docker guide prerequisites before starting. For Linux desktops or servers, use [Docker](/docs/local/docker), [npm](/docs/local/npm), or a [remote hosting guide](/docs/remote).

</Callout>
24 changes: 17 additions & 7 deletions content/docs/quick_start/local_setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,30 @@ git clone https://github.com/LibreChat-AI/LibreChat.git

## Step 3. Run the App

1. **Navigate to the Project Directory**
1. **Navigate to the Project Directory**: Open a terminal in the `LibreChat` folder you cloned or extracted in Step 1. If you used Git:

2. **Create and Configure .env File**:
- Copy the contents of `.env.example` to a new file named `.env`.
- Fill in any necessary values.
- For an in-depth environment configuration, see the [.env File Configuration Guide](/docs/configuration/dotenv).
```bash
cd LibreChat
```

3. **Start the Application**:
- Run the following command:
2. **Create the .env File**: Copy `.env.example` to a new file named `.env`:

```bash
cp .env.example .env
```

On Windows, use `copy .env.example .env` if `cp` is not available.

The default values work out of the box for a basic local setup. For in-depth environment configuration, see the [.env File Configuration Guide](/docs/configuration/dotenv).

3. **Start the Application**: Make sure Docker Desktop is running, then run:

```bash
docker compose up -d
```

The first launch downloads the Docker images and may take a few minutes. Subsequent starts are much faster. If a container stops right after starting, see the [Docker guide troubleshooting section](/docs/local/docker#troubleshooting).

## Step 4. Start Chatting

LibreChat is now running, but it needs an account and a model before it can answer anything:
Expand Down
114 changes: 114 additions & 0 deletions e2e/quick-start-install-steps.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { expect, test, type Page } from '@playwright/test'

function body(page: Page) {
return page.locator('#nd-page')
}

// The final step each locale shows on the Docker and npm cards. The hub copy is
// hand-maintained per locale, so every dictionary has to carry it.
const OPEN_AND_REGISTER: Record<string, string> = {
en: 'Open localhost:3080 and register',
de: 'localhost:3080 öffnen und registrieren',
es: 'Abre localhost:3080 y regístrate',
fr: 'Ouvrez localhost:3080 et inscrivez-vous',
id: 'Buka localhost:3080 dan daftar',
it: 'Apri localhost:3080 e registrati',
ja: 'localhost:3080 を開いてアカウント登録',
ko: 'localhost:3080을 열고 계정 등록',
nl: 'Open localhost:3080 en registreer',
pl: 'Otwórz localhost:3080 i zarejestruj się',
'pt-BR': 'Abra localhost:3080 e cadastre-se',
tr: 'localhost:3080 adresini açın ve kaydolun',
vi: 'Mở localhost:3080 và đăng ký',
zh: '打开 localhost:3080 并注册',
}

async function cardSteps(page: Page, method: string) {
// Each item is a number badge followed by the step label; read the label only.
return page
.getByRole('list', { name: `${method} steps` })
.getByRole('listitem')
.locator('span:last-child')
.allInnerTexts()
}

test.describe('Quick Start install steps', () => {
test('@scenario:quick-start-cards-end-at-first-login the Docker and npm cards end with opening LibreChat and registering', async ({
page,
}) => {
await page.goto('/docs/quick_start')

for (const method of ['Docker', 'npm']) {
const steps = await cardSteps(page, method)
expect(steps).toHaveLength(4)
expect(steps[3].trim()).toBe(OPEN_AND_REGISTER.en)
}

// The npm card must match the Node.js version the npm guide pins.
await expect(body(page).getByText('Node.js v24.16.0', { exact: true })).toBeVisible()
await expect(body(page).getByText('Node.js v20.19+')).toHaveCount(0)
})

test('@scenario:quick-start-cards-localized-in-every-locale every locale shows the first-login step and the current Node.js version', async ({
page,
}) => {
for (const [locale, step] of Object.entries(OPEN_AND_REGISTER)) {
if (locale === 'en') continue
await page.goto(`/${locale}/docs/quick_start`)
for (const method of ['Docker', 'npm']) {
const steps = await cardSteps(page, method)
expect(steps, `${locale} ${method}`).toHaveLength(4)
expect(steps[3].trim(), `${locale} ${method}`).toBe(step)
}
await expect(body(page).getByText('Node.js v24.16.0', { exact: true })).toBeVisible()
}
})

test('@scenario:local-setup-gives-exact-run-commands the Local Setup guide gives the commands to run, in order', async ({
page,
}) => {
await page.goto('/docs/quick_start/local_setup')

const commands = (await body(page).locator('pre').allInnerTexts()).map((text) => text.trim())
const expected = ['cd LibreChat', 'cp .env.example .env', 'docker compose up -d']
const positions = expected.map((command) => commands.indexOf(command))
expect(
positions.every((position) => position >= 0),
commands.join(' | '),
).toBe(true)
expect([...positions].sort((a, b) => a - b)).toEqual(positions)

await expect(body(page).getByText('copy .env.example .env')).toBeVisible()

// Step 4 still hands the reader to the first-chat walkthrough. Checked
// before leaving the page: the Docker guide links there too. Exact match
// skips the footer's next-page card, which exists regardless of Step 4.
await expect(
body(page).getByRole('link', { name: 'Your First Chat', exact: true }),
).toHaveAttribute('href', '/docs/quick_start/first_chat')

// The failure path points somewhere that exists.
const troubleshooting = body(page).getByRole('link', {
name: 'Docker guide troubleshooting section',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Check the handoff before leaving the setup page

Move the Your First Chat assertion before this click (or navigate back afterward). The click navigates from Local Setup to the Docker troubleshooting section, and the Docker guide independently contains a Your First Chat link, so the test still passes if the newly documented Step 4 handoff is later removed or given an incorrect URL.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 1300210: the handoff assertion now runs on Local Setup before the click into the Docker guide. f75f363 also matches the link exactly, because the footer's next-page card links to Your First Chat too and would have masked a missing Step 4 link. @Scenario:local-setup-gives-exact-run-commands passes in the End-to-end tests job on f75f363 (62/62).

})
await expect(troubleshooting).toHaveAttribute('href', '/docs/local/docker#troubleshooting')
await troubleshooting.click()
await expect(page).toHaveURL(/\/docs\/local\/docker#troubleshooting$/)
await expect(page.locator('#troubleshooting')).toBeVisible()
})

test('@scenario:docs-landing-desktop-callout-covers-macos the desktop installer callout tells Mac readers what to use', async ({
page,
}) => {
await page.goto('/docs')

const callout = body(page).getByText('Looking for a desktop installer?').locator('..')
await expect(callout).toContainText('On macOS, also use Docker Desktop')
await expect(callout).toContainText('Apple Silicon (M-series)')
const dockerLinks = callout.getByRole('link', { name: 'Docker Desktop' })
await expect(dockerLinks).toHaveCount(2)
for (const link of await dockerLinks.all()) {
await expect(link).toHaveAttribute('href', '/docs/local/docker')
}
})
})
10 changes: 8 additions & 2 deletions lib/ui-i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,12 @@ const en = {
tag: 'Recommended',
time: '~5 min',
description: 'Everything included — MongoDB, MeiliSearch, and RAG API run automatically.',
steps: ['Clone the repository', 'Copy .env.example to .env', 'Run docker compose up'],
steps: [
'Clone the repository',
'Copy .env.example to .env',
'Run docker compose up',
'Open localhost:3080 and register',
],
prereqs: ['Docker Desktop'],
},
npm: {
Expand All @@ -138,8 +143,9 @@ const en = {
'Clone and install dependencies',
'Configure .env and start MongoDB',
'Run npm run backend',
'Open localhost:3080 and register',
],
prereqs: ['Node.js v20.19+', 'MongoDB instance'],
prereqs: ['Node.js v24.16.0', 'MongoDB instance'],
},
railway: {
tag: 'One-click',
Expand Down
4 changes: 3 additions & 1 deletion lib/ui-translations/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export const de: UIStrings = {
'Repository klonen',
'.env.example nach .env kopieren',
'docker compose up ausführen',
'localhost:3080 öffnen und registrieren',
],
prereqs: ['Docker Desktop'],
},
Expand All @@ -115,8 +116,9 @@ export const de: UIStrings = {
'Klonen und Abhängigkeiten installieren',
'.env konfigurieren und MongoDB starten',
'npm run backend ausführen',
'localhost:3080 öffnen und registrieren',
],
prereqs: ['Node.js v20.19+', 'MongoDB-Instanz'],
prereqs: ['Node.js v24.16.0', 'MongoDB-Instanz'],
},
railway: {
tag: 'Ein-Klick',
Expand Down
4 changes: 3 additions & 1 deletion lib/ui-translations/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export const es: UIStrings = {
'Clonar el repositorio',
'Copiar .env.example a .env',
'Ejecutar docker compose up',
'Abre localhost:3080 y regístrate',
],
prereqs: ['Docker Desktop'],
},
Expand All @@ -118,8 +119,9 @@ export const es: UIStrings = {
'Clonar e instalar dependencias',
'Configurar .env e iniciar MongoDB',
'Ejecutar npm run backend',
'Abre localhost:3080 y regístrate',
],
prereqs: ['Node.js v20.19+', 'Instancia de MongoDB'],
prereqs: ['Node.js v24.16.0', 'Instancia de MongoDB'],
},
railway: {
tag: 'Un clic',
Expand Down
10 changes: 8 additions & 2 deletions lib/ui-translations/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,12 @@ export const fr: UIStrings = {
time: '~5 min',
description:
"Tout est inclus — MongoDB, MeiliSearch et RAG API s'exécutent automatiquement.",
steps: ['Cloner le dépôt', 'Copier .env.example vers .env', 'Exécuter docker compose up'],
steps: [
'Cloner le dépôt',
'Copier .env.example vers .env',
'Exécuter docker compose up',
'Ouvrez localhost:3080 et inscrivez-vous',
],
prereqs: ['Docker Desktop'],
},
npm: {
Expand All @@ -115,8 +120,9 @@ export const fr: UIStrings = {
'Cloner et installer les dépendances',
'Configurer .env et démarrer MongoDB',
'Exécuter npm run backend',
'Ouvrez localhost:3080 et inscrivez-vous',
],
prereqs: ['Node.js v20.19+', 'Instance MongoDB'],
prereqs: ['Node.js v24.16.0', 'Instance MongoDB'],
},
railway: {
tag: 'En un clic',
Expand Down
10 changes: 8 additions & 2 deletions lib/ui-translations/id.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,12 @@ export const id: UIStrings = {
time: '~5 mnt',
description:
'Semuanya sudah termasuk — MongoDB, MeiliSearch, dan RAG API berjalan otomatis.',
steps: ['Clone repository', 'Salin .env.example ke .env', 'Jalankan docker compose up'],
steps: [
'Clone repository',
'Salin .env.example ke .env',
'Jalankan docker compose up',
'Buka localhost:3080 dan daftar',
],
prereqs: ['Docker Desktop'],
},
npm: {
Expand All @@ -111,8 +116,9 @@ export const id: UIStrings = {
'Clone dan instal dependensi',
'Konfigurasikan .env dan mulai MongoDB',
'Jalankan npm run backend',
'Buka localhost:3080 dan daftar',
],
prereqs: ['Node.js v20.19+', 'Instance MongoDB'],
prereqs: ['Node.js v24.16.0', 'Instance MongoDB'],
},
railway: {
tag: 'Sekali klik',
Expand Down
10 changes: 8 additions & 2 deletions lib/ui-translations/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,12 @@ export const it: UIStrings = {
time: '~5 min',
description:
'Tutto incluso — MongoDB, MeiliSearch e RAG API vengono eseguiti automaticamente.',
steps: ['Clona il repository', 'Copia .env.example in .env', 'Esegui docker compose up'],
steps: [
'Clona il repository',
'Copia .env.example in .env',
'Esegui docker compose up',
'Apri localhost:3080 e registrati',
],
prereqs: ['Docker Desktop'],
},
npm: {
Expand All @@ -111,8 +116,9 @@ export const it: UIStrings = {
'Clona e installa le dipendenze',
'Configura .env e avvia MongoDB',
'Esegui npm run backend',
'Apri localhost:3080 e registrati',
],
prereqs: ['Node.js v20.19+', 'Istanza MongoDB'],
prereqs: ['Node.js v24.16.0', 'Istanza MongoDB'],
},
railway: {
tag: 'Un clic',
Expand Down
4 changes: 3 additions & 1 deletion lib/ui-translations/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export const ja: UIStrings = {
'リポジトリをクローン',
'.env.example を .env にコピー',
'docker compose up を実行',
'localhost:3080 を開いてアカウント登録',
],
prereqs: ['Docker Desktop'],
},
Expand All @@ -118,8 +119,9 @@ export const ja: UIStrings = {
'クローンして依存関係をインストール',
'.env を設定し MongoDB を起動',
'npm run backend を実行',
'localhost:3080 を開いてアカウント登録',
],
prereqs: ['Node.js v20.19+', 'MongoDB インスタンス'],
prereqs: ['Node.js v24.16.0', 'MongoDB インスタンス'],
},
railway: {
tag: 'ワンクリック',
Expand Down
16 changes: 13 additions & 3 deletions lib/ui-translations/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,26 @@ export const ko: UIStrings = {
time: '~5분',
description:
'모든 것이 포함되어 있습니다 — MongoDB, MeiliSearch, RAG API가 자동으로 실행됩니다.',
steps: ['저장소 복제', '.env.example을 .env로 복사', 'docker compose up 실행'],
steps: [
'저장소 복제',
'.env.example을 .env로 복사',
'docker compose up 실행',
'localhost:3080을 열고 계정 등록',
],
prereqs: ['Docker Desktop'],
},
npm: {
tag: '',
time: '~20분',
description:
'Node.js를 사용한 수동 설정입니다. 별도의 MongoDB 및 MeiliSearch 인스턴스가 필요합니다.',
steps: ['복제하고 의존성 설치', '.env 구성 및 MongoDB 시작', 'npm run backend 실행'],
prereqs: ['Node.js v20.19+', 'MongoDB 인스턴스'],
steps: [
'복제하고 의존성 설치',
'.env 구성 및 MongoDB 시작',
'npm run backend 실행',
'localhost:3080을 열고 계정 등록',
],
prereqs: ['Node.js v24.16.0', 'MongoDB 인스턴스'],
},
railway: {
tag: '원클릭',
Expand Down
4 changes: 3 additions & 1 deletion lib/ui-translations/nl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export const nl: UIStrings = {
'Clone de repository',
'Kopieer .env.example naar .env',
'Voer docker compose up uit',
'Open localhost:3080 en registreer',
],
prereqs: ['Docker Desktop'],
},
Expand All @@ -114,8 +115,9 @@ export const nl: UIStrings = {
'Clone en installeer afhankelijkheden',
'Configureer .env en start MongoDB',
'Voer npm run backend uit',
'Open localhost:3080 en registreer',
],
prereqs: ['Node.js v20.19+', 'MongoDB-instantie'],
prereqs: ['Node.js v24.16.0', 'MongoDB-instantie'],
},
railway: {
tag: 'Eén klik',
Expand Down
4 changes: 3 additions & 1 deletion lib/ui-translations/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export const pl: UIStrings = {
'Sklonuj repozytorium',
'Skopiuj .env.example do .env',
'Uruchom docker compose up',
'Otwórz localhost:3080 i zarejestruj się',
],
prereqs: ['Docker Desktop'],
},
Expand All @@ -115,8 +116,9 @@ export const pl: UIStrings = {
'Sklonuj i zainstaluj zależności',
'Skonfiguruj .env i uruchom MongoDB',
'Uruchom npm run backend',
'Otwórz localhost:3080 i zarejestruj się',
],
prereqs: ['Node.js v20.19+', 'Instancja MongoDB'],
prereqs: ['Node.js v24.16.0', 'Instancja MongoDB'],
},
railway: {
tag: 'Jedno kliknięcie',
Expand Down
Loading
Loading