Open-Source Wikis

/

GitLab

/

Apps

/

Frontend

gitlab-org/gitlab

Frontend

GitLab's web UI: a hybrid Rails-rendered + Vue.js single-page application stack with ~10,500 JS files and ~4,500 Vue components in this repo.

Purpose

Render every screen the user sees in their browser, including:

  • Project, group, and admin pages.
  • Issues, merge requests, work items, epics.
  • The Web IDE.
  • The CI/CD pipeline editor and live trace viewer.
  • The diff browser, code review tools.
  • Duo Chat, code suggestions UX, agent surfaces.
  • Dashboards, observability views.

Three flavors of frontend

graph TD
    HAML[Server-rendered HAML in app/views/]
    Vue[Vue apps in app/assets/javascripts/<feature>/]
    Islands[Standalone islands in frontend_islands/]

    HAML -->|mounts| Vue
    HAML -->|mounts| Islands
    Vue -->|GraphQL/REST| Backend[Rails backend]
    Islands -->|GraphQL/REST| Backend
  1. Rails-rendered HAML — most pages still render their initial shell server-side (app/views/, ee/app/views/). HAML files mount Vue components into anchor divs.
  2. Vue / Vuex applications mounted into HAML containers, organized by feature under app/assets/javascripts/<feature>/ and ee/app/assets/javascripts/<feature>/. Each entry point sits at <feature>/index.js or <feature>/main.js.
  3. Frontend islands — independently bundled, mounted into specific HAML containers. Built by Vite (vite.config.js) instead of Webpack. Live in frontend_islands/ and ee/frontend_islands/. The script scripts/build_frontend_islands orchestrates the per-island build.

Source tree

app/assets/
├── javascripts/                # ~235 top-level feature directories
│   ├── api.js                  # Generic REST client wrapping axios
│   ├── boards/                 # Issue boards
│   ├── ci/                     # CI/CD pipeline editor, runners, etc.
│   ├── ide/                    # Web IDE
│   ├── ai/                     # Duo Chat & related UI
│   ├── work_items/             # Work items framework
│   ├── pipelines/              # Pipeline list / details
│   ├── merge_requests/         # MR view, code review
│   ├── notes/                  # Comment threads
│   ├── analytics/              # Analytics dashboards
│   ├── lib/utils/              # Shared utilities
│   ├── vue_shared/             # Reusable Vue components
│   └── ...                     # ~200+ more feature dirs
├── stylesheets/                # SCSS (~15 top-level groups)
└── images/                     # Bundled imagery
frontend_islands/               # FOSS islands (Vite-built)
ee/frontend_islands/            # EE-only islands

Build pipeline

Bundle Tool Config
Main JS bundle Webpack config/webpack.config.js (~36K LoC)
Frontend islands Vite vite.config.js, config/vite.json
Tailwind utilities PostCSS + Tailwind config/tailwind.config.js
Storybook Storybook + Vite storybook/
Asset compilation in CI Rake scripts/compile_assets

Webpack is responsible for the large main bundle; Vite handles smaller, faster-rebuilding islands.

State and data

  • GraphQL via Apollo — client setup in app/assets/javascripts/lib/graphql.js. Many features use GraphQL exclusively.
  • REST via axios — wrapped by app/assets/javascripts/api.js and feature-specific clients.
  • Vuex — feature stores under app/assets/javascripts/<feature>/store/. Pinia is approved for new code.
  • Apollo cache — for cross-component reactive state.

GraphQL queries and mutations are co-located with components: <feature>/graphql/queries/foo.query.graphql and compiled by vue-apollo's loader.

Component library

UI components come from @gitlab/ui (separate repo). The codebase explicitly forbids inline buttons, modals, dropdowns, etc. — use the GitLab UI components.

Internal Vue shared components live in app/assets/javascripts/vue_shared/components/.

Vue 2 → Vue 3 migration

config/vue3migration/ tracks per-component migration status. New components are written for Vue 3. Some legacy components still rely on Vue 2; they're being incrementally rewritten.

Testing the frontend

  • Jest — primary test runner (yarn jest).
  • Vue Test Utils — component mounting in tests.
  • MSW — Mock Service Worker for HTTP-level integration tests.
  • Pact contract testsjest.config.contract.js.
  • Snapshot testsjest.config.snapshots.js.

Specs live at spec/frontend/<mirror of source>/<file>.spec.js. EE specs live at ee/spec/frontend/.

See Testing.

Linting and formatting

  • ESLint (eslint.config.mjs) — ~28K LoC config, includes custom GitLab rules in tooling/eslint-rules/.
  • Stylelint (.stylelintrc).
  • Prettier (.prettierrc).

Custom ESLint plugins enforce:

  • no-unsanitized — no innerHTML.
  • vue-no-new-non-primitive-in-template — perf rule.
  • Rules for GraphQL fragment usage.
  • Rules forbidding direct fetch/axios outside the wrappers.

i18n

User-facing strings flow through __('...') (gettext) on the frontend. Strings are extracted by bin/rake gettext:regenerate and translated in locale/<lang>/gitlab.po.

Storybook

storybook/ provides a component playground. Run with yarn storybook. Stories live alongside their components.

Performance budgets

The repo's bundle_size_review script runs in CI and compares main-bundle size MR-over-MR. Bundlers also produce stats artifacts published to GitLab Pages for inspection.

Where to make changes

  • New component: under app/assets/javascripts/<feature>/components/ plus a Jest spec.
  • New page: a feature directory with index.js, mount it from a HAML view.
  • New island: under frontend_islands/<name>/ with its own vite.config.js extension.
  • New shared utility: app/assets/javascripts/lib/utils/.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Frontend – GitLab wiki | Factory