Skip to content

Conversation

@g-francesca
Copy link
Collaborator

@g-francesca g-francesca commented Jan 28, 2026

Note

There’s no preview link, @bjohansebas working on fixing that

This PR introduces a complete Astro-based rebuild of the Express.js documentation site, establishing the foundational architecture, design system, and UI component library. The work includes:

  • Astro 5 project setup
  • Design system setup with tokens and primitives
  • Content layer configuration with routing system
  • i18n infrastructure for multi-language support
  • Living documentation of all design foundations

Project Setup & Infrastructure

Astro 5 Configuration

  • Initialized Astro 5 project with latest features including Content Layer API
  • Configured Astro with MDX support
  • Set up PostCSS with custom media queries, autoprefixer, and cssnano
  • Established Node.js (≥24.13.0) and npm (≥11.0.0) requirements

Development Tooling

  • ESLint: Configured with Astro, TypeScript, JSX a11y, and Prettier integration
  • Prettier: Set up with Astro plugin for consistent code formatting
  • VSCode: Added workspace settings, recommended extensions, and launch configurations
  • Git: Updated .gitignore and .editorconfig for better project hygiene
  • Package Manager: Enforced npm usage with preinstall checks

Design System Foundations

Design Tokens

A complete token system following semantic naming conventions, organized in modular CSS files:

Color System

  • Primitive color scales: gray (50-950), sky, green, amber, red, white/black
  • Semantic tokens for consistent usage:
    • Background: --color-bg-{primary|secondary|tertiary|inverse|mute|success|warning|error}
    • Text: --color-text-{primary|secondary|tertiary|inverse|mute|success|warning|error}
    • Border: --color-border-{primary|secondary|tertiary|inverse|mute|success|warning|error}
    • Icons: --color-icon-{primary|secondary|tertiary|inverse}
  • Theme-aware colors with CSS custom properties supporting light/dark modes

Typography

  • Type scale: xs (12px) → 6xl (54px)
  • Font families: Inter (system), JetBrains Mono (code)
  • Font weights: light (300) → bold (700)
  • Line heights optimized for readability
  • Responsive font sizing with fluid typography

Spacing

  • Consistent scale from 0.5 (2px) to 16 (64px)
  • Based on 4px grid system
  • Tokens: --space-{0.5|1|2|3|4|6|8|12|16}

Breakpoints

  • Mobile-first approach with custom media queries
  • xs: < 768px (mobile)
  • md: 768px - 1439px (tablet)
  • lg: ≥ 1440px (desktop)
  • Range queries: --xs, --md, --lg, --md-up, --md-down, --lg-down

Additional Tokens

  • Borders: radius, widths
  • Transitions: durations and timing functions

Component Library

Primitive Components

Fully composable, polymorphic UI primitives:

Typography Components

Heading Components:

  • <H1> through <H5> - Semantic heading components
  • Responsive sizing with mobile/desktop variants
  • Support for color variants (primary, secondary, tertiary, etc.)

Body Text Components:

  • <Body> - Default paragraph text (16px)
  • <BodyMd> - Medium body text (15px)
  • <BodySm> - Small body text (14px)
  • <BodyXs> - Extra small text (12px)

Code Component:

  • <Code> - Inline code styling with monospace font

Features:

  • Polymorphic rendering: <H1 as="h2"> renders h2 with H1 styling
  • Color variants: primary, secondary, tertiary, inverse, mute, status colors
  • Weight control: light, normal, medium, semibold, bold
  • Align control: left, center, right

Layout Components

Grid System

  • <Grid> - 12-column responsive grid container
  • <Col> - Grid column with responsive sizing
    • Props: xs, md, lg (1-12)
    • Cascading breakpoints (xs → md → lg)
  • Gap control using spacing tokens

Flexbox Components

  • <Flex> - Flexbox container with comprehensive props
    • Direction: row, column
    • Justify: start, center, end, between, around
    • Align: start, center, end, stretch, baseline
    • Gap control
  • <FlexItem> - Individual flex item control
    • Flex: 1, auto, initial, none
    • Grow: boolean
    • Shrink: boolean
    • Basis: auto, 1/4, 1/3, 1/2, 2/3, 3/4, full

Container

  • <Container> - Centered content wrapper
  • Max-width: 1440px
  • Responsive padding (90% mobile → 95% desktop)

Button Component

Features:

  • Variants: primary, secondary
  • Sizes: xs, sm, md
  • Ghost style for transparent backgrounds
  • Disabled state
  • Polymorphic rendering (button/a)
  • Icon support

Styling:

  • Smooth transitions and hover states
  • Disabled state with reduced opacity and no pointer events

Pattern Components

Please note that these are wip.

  • ThemeSwitcher - Light/dark theme toggle with local storage persistence
  • Breadcrumbs - Navigation breadcrumb component

i18n Infrastructure

Features:

  • Language detection from URL patterns (/[lang]/...)
  • Translation utilities with type safety
  • Default language fallback (English)
  • Initial support for English only (French added for testing purposes only)
  • Extensible for additional languages

Files:

  • /src/i18n/ui.ts - Language definitions and translation strings
  • /src/i18n/utils.ts - getLangFromUrl() and useTranslations() helpers

Routing & Content Layer

Astro 5 Content Layer API

Features:

  • Uses new glob loader pattern for flexible content sourcing
  • Content stored in src/data/docs/ (same will be done for blog posts)
  • Zod schema validation for frontmatter
  • Support for sections: starter, guide, advanced, resources

Routing Structure

Dynamic routes in src/pages/[lang]/

  • /[lang]/ - Home page with language detection
  • /[lang]/ds-foundations - Living design system documentation - Please note that this is a temporary page, built to provide a living reference for the design system, to facilitate review and test.
  • /[lang]/docs/index - Living docs documentation - Please note that this is a temporary page, built to facilitate dynamic routing system review.
  • Future routes ready for expansion

Notes

Legacy App
Jekyll app has been moved under legacy folder with zero changes

Figma diffs

  • While implementing the design system foundations, an optimization and rationalization process was undertaken to translate Figma designs into production-ready, composable UI components.

There may be some minor differences between the Figma designs and the implemented components. These differences are intentional and result from:

  1. Removing small inconsistencies found in Figma
  2. Standardizing component APIs for better developer experience
  3. Optimizing for web performance and accessibility
  4. Following established web standards and best practices

Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or

(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or

(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.

(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.

@g-francesca g-francesca requested review from a team as code owners January 28, 2026 17:39
@socket-security
Copy link

socket-security bot commented Jan 28, 2026

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm entities is 91.0% likely obfuscated

Confidence: 0.91

Location: Package overview

From: astro/package-lock.jsonnpm/astro@5.16.11npm/astro-icon@1.1.5npm/entities@4.5.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/entities@4.5.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm entities is 91.0% likely obfuscated

Confidence: 0.91

Location: Package overview

From: astro/package-lock.jsonnpm/@astrojs/mdx@4.3.13npm/astro@5.16.11npm/astro-icon@1.1.5npm/eslint-plugin-astro@1.5.0npm/entities@6.0.1

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/entities@6.0.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm safer-buffer is 94.0% likely obfuscated

Confidence: 0.94

Location: Package overview

From: astro/package-lock.jsonnpm/astro-icon@1.1.5npm/safer-buffer@2.1.2

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/safer-buffer@2.1.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm svgo is 91.0% likely obfuscated

Confidence: 0.91

Location: Package overview

From: astro/package-lock.jsonnpm/astro-icon@1.1.5npm/svgo@3.3.2

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/svgo@3.3.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm vite is 91.0% likely obfuscated

Confidence: 0.91

Location: Package overview

From: astro/package-lock.jsonnpm/astro@5.16.11npm/vite@6.4.1

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/vite@6.4.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report


:root {
--breakpoint-xs: 768px;
--breakpoint-md: 1440px;
Copy link
Collaborator Author

@g-francesca g-francesca Jan 28, 2026

Choose a reason for hiding this comment

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

  • --breakpoint-lg is missing

/* Status */
--color-success: var(--green-500);
--color-warning: var(--amber-500);
--color-error: var(--red-500);
Copy link
Collaborator Author

@g-francesca g-francesca Jan 28, 2026

Choose a reason for hiding this comment

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

  • These can be removed as replaced by more appropriate semantic tokens (ie --color-text-warning)

--space-section: var(--space-16);
--space-component: var(--space-6);
--space-element: var(--space-4);
--space-inline: var(--space-2);
Copy link
Collaborator Author

@g-francesca g-francesca Jan 28, 2026

Choose a reason for hiding this comment

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

  • These can be removed as no longer in use

│ ├── components/ # Reusable UI components
│ ├── layouts/ # Page layouts
│ ├── pages/ # Route pages
│ └── styles/ # Global styles
Copy link
Collaborator Author

@g-francesca g-francesca Jan 28, 2026

Choose a reason for hiding this comment

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

  • i18n and content folder missing

Copy link
Member

@bjohansebas bjohansebas left a comment

Choose a reason for hiding this comment

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

LGTM. I don’t have any major concerns other than removing the preinstall script and using devEngines instead. Everything else can be handled in future PRs. Great work!

Comment on lines 20 to 24
},
"workbench.colorCustomizations": {
"titleBar.activeBackground": "#0075d4",
"titleBar.inactiveBackground": "#0075d4"
}
Copy link
Member

Choose a reason for hiding this comment

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

please remove this

Suggested change
},
"workbench.colorCustomizations": {
"titleBar.activeBackground": "#0075d4",
"titleBar.inactiveBackground": "#0075d4"
}
}

Copy link
Member

Choose a reason for hiding this comment

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

Could we use a package instead, rather than keeping our own files in the repository? For example, https://www.npmjs.com/package/@fontsource/jetbrains-mono
. I mention this because I don’t want to have future PRs just to update those files “to update those assets.” Also, it’s a trustworthy package. I’m not saying to do it in this PR, but maybe in the next ones

Copy link
Collaborator Author

@g-francesca g-francesca Jan 29, 2026

Choose a reason for hiding this comment

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

@bjohansebas I used local fonts here because, based on the design, we only need the light font weight. That means just two font files (191 KB total), so I went with a local setup using optimized woff2 files and proper font-display settings, instead of introducing an additional npm dependency.
I have no strong preference though. Happy to move to @fontsource if that’s the preference. I can quickly handle in this PR, let me know. TY!

Copy link
Member

Choose a reason for hiding this comment

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

Let’s keep it this way in this PR. We can iterate later.

Copy link
Member

Choose a reason for hiding this comment

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

I think we haven’t chosen the logo yet, or at least I haven’t been informed, but let’s keep it for now.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for the info, I will keep a note of this for future checks.

"type": "module",
"version": "0.0.1",
"scripts": {
"preinstall": "npx only-allow npm",
Copy link
Member

Choose a reason for hiding this comment

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

Let’s use devEngines, it’s safer and supported by all the major package managers. This should be a requirement.

https://docs.npmjs.com/cli/v11/configuring-npm/package-json#devengines

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm replacing it! Thanks for the suggestion

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@bjohansebas I tried replacing the preinstall script with devEngines, but I understand they serve different purposes. devEngines enforces node/npm versions, but only when npm is used. My original goal with preinstall was to explicitly prevent installs via pnpm/yarn/bun and enforce npm as the package manager. So, for example, pnpm i would fail only because of the preinstall check, not with devEngines.

We can agree this isn’t strictly necessary, since the presence of package-lock.json already implies npm, but I added it as an explicit guardrail.

I'm keeping the devEngines field since it’s useful. Given the above, not sure whether we keep or remove the preinstall script. Let me know! TY

Copy link
Member

Choose a reason for hiding this comment

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

But pnpm also supports it. Yarn can only be used via Corepack, which no longer exists in newer Node.js versions, and I’m not sure whether Bun supports it, although I’d say it probably does.

https://pnpm.io/package_json#devenginesruntime
, but in any case, let’s remove the preinstall script.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done ✅

title: Developing template engines for Express
description: Learn how to develop custom template engines for Express.js using app.engine(), with examples on creating and integrating your own template rendering logic.
menu: advanced
order: 1
Copy link
Member

Choose a reason for hiding this comment

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

I’d like us to stop having this and instead rely on logic to determine the order. If I remember correctly, Starlight handles it based on the menu order. This isn’t a blocker for this PR, just something I’d like to handle in future PRs

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Makes sense. I wasn't actually sure about keeping menu and order; we can likely clean them up when building the menu. I'm keeping a note of this.

Copy link
Member

Choose a reason for hiding this comment

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

Not blocking for this PR, but is this really necessary?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I double-checked this, and I would keep using PostCSS as a minimal layer for CSS feature support. Since Astro already includes PostCSS, this doesn’t add any meaningful overhead. In particular, I’m using @Custom-Media, which isn’t natively supported by browsers yet, and it simplifies working with media queries. We can use intuitive syntax like: @media (--lg-down) { // Style to apply below desktop breakpoint }

On the other hand, I'm removing autoprefixer and cssnano. We can rely on Astro built-in minification, and given our modern-browser support requirements, we don’t need additional prefixing.
wdyt?

Copy link
Member

Choose a reason for hiding this comment

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

Not for this PR, but for future ones, I’d like each language to be handled as a separate JSON. I’m concerned it could end up being a fairly large JavaScript file.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Makes a lot of sense. I'm keeping a note of this for the moment when we'll cover other languages.

Comment on lines +9 to +10
menu: z.string(),
order: z.number().optional(),
Copy link
Member

Choose a reason for hiding this comment

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

These two things should ideally not be necessary. For future PRs, we should try to remove them, I understand this is just part of the initial setup, just something to keep in mind.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Agree and noted.

Comment on lines +25 to +29
files: ['**/*.{jsx,tsx}'],
plugins: {
'jsx-a11y': jsxA11y,
},
rules: jsxA11y.configs.recommended.rules,
Copy link
Member

Choose a reason for hiding this comment

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

For reference, the search will use React, since that’s Orama’s recommendation. It’s the only part that will use React, the rest will be handled with plain JavaScript.

@bjohansebas
Copy link
Member

Oh, and I almost forgot, please move the license file to the root of the project. It’s not that we forgot about it when we remove the legacy folder

@carlosstenzel
Copy link
Contributor

Can we have a preview link?

@bjohansebas
Copy link
Member

bjohansebas commented Jan 28, 2026

Can we have a preview link?

Working on it. I’m not sure why Netlify didn’t work for the previews, so I need access to Netlify, which I don’t currently have. I’ll bring this up in today’s meeting

Edit: the members who were present don’t have access to Netlify, so I’ll have to wait for @jonchurch to grant me access

@g-francesca
Copy link
Collaborator Author

Oh, and I almost forgot, please move the license file to the root of the project. It’s not that we forgot about it when we remove the legacy folder

Right! Moving it! Thanks

Copy link
Member

@UlisesGascon UlisesGascon left a comment

Choose a reason for hiding this comment

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

RLGTM! The setup and project base is clear, great work @g-francesca!. There quite few things that we can improve, but I think that we can address that on separate PRs and try to land this PR soon to unblock progress on other areas.

Not a blocker but I think that maybe adding a GitHub Action pipeline for the redesign branch might help us to keep smaller PRs in the future and prevent pollution from prettier, etc...

BTW.. I was having some issues to run the build and dev commands:

Image Image

Ops, right! This was caused by Prettier multiline formatting of TS union types and esbuild having trouble parsing this syntax ins Astro file frontmatter section. To avoid that, I moved types definition to a separate file. @UlisesGascon Can you please try again now? I expect you being able to run dev and build commands.

@g-francesca g-francesca merged commit 20332be into redesign Jan 29, 2026
3 checks passed
@bjohansebas bjohansebas deleted the redesign-astro-setup branch January 29, 2026 15:05
@jonchurch
Copy link
Member

jonchurch commented Jan 29, 2026

I just set it so all the branches in this repo will get deployed to netlify for preview.

That should trigger deploy previews for all PRs as well I believe

@bjohansebas
Copy link
Member

thanks @jonchurch

@bjohansebas
Copy link
Member

bjohansebas commented Jan 29, 2026

But could you give me access for anything? It seems you’re the only person there, and I’m not sure if Rand also has access

To avoid the bus factor.

edit: thanks, now i have access

@UlisesGascon
Copy link
Member

(...) @UlisesGascon Can you please try again now? I expect you being able to run dev and build commands.

Yeah @g-francesca! It is working great now! 🥳

....
18:15:08   ├─ /en/resources/middleware/multer/index.html (+2ms) 
18:15:09   ├─ /en/resources/middleware/serve-favicon/index.html (+2ms) 
18:15:09   ├─ /en/resources/middleware/serve-index/index.html (+1ms) 
18:15:09   ├─ /en/resources/middleware/serve-static/index.html (+4ms) 
18:15:09   ├─ /en/resources/middleware/session/index.html (+3ms) 
18:15:09   ├─ /en/resources/middleware/timeout/index.html (+2ms) 
18:15:09   └─ /en/resources/middleware/vhost/index.html (+1ms) 
18:15:09 ▶ src/pages/index.astro
18:15:09   └─ /index.html (+1ms) 
18:15:09 ✓ Completed in 412ms.

18:15:09 [build] 52 page(s) built in 1.64s
18:15:09 [build] Complete!
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants