Project structure

The UluBit Astro Starter provides a standard project structure so common responsibilities have predictable places from the beginning.

Most of the structure is a project convention rather than an Astro requirement. Keep the default structure when it fits the project, and adapt it when the project has a clear reason to organize something differently.

Structure

A new project includes the following main structure:

public/
src/
├── assets/
├── components/
├── layouts/
├── pages/
├── styles/
├── utils/
├── site.config.ts
└── types.ts

astro.config.mjs
package.json
pnpm-workspace.yaml
tsconfig.json

Most project source code lives inside src/. Static files that should be served without being processed by Astro live in public/.

Assets

src/assets/

Use assets for project images and other assets that are imported into the source code and processed as part of the build.

The starter logo lives here:

src/assets/logo.svg

Files that need to be served unchanged instead belong in public/.

Components

src/components/

Use components for reusable pieces of the project’s interface and structure.

The starter includes components for its site shell and common behavior, such as the header, footer, branding, navigation, metadata, analytics, and formatted dates.

Reusable interface components are also available from @ulubit/ui. Use them when they provide the component the project needs, while keeping project-specific components and compositions in the project.

Layouts

src/layouts/

Use layouts for document or page structure shared across multiple routes.

The starter includes:

src/layouts/BaseLayout.astro

BaseLayout provides the common document shell, metadata, global styles, header, footer, and page-content slot.

Pages remain responsible for the semantic structure of their own content. The base layout includes a skip link targeting #main-content, so pages using it should provide that target:

<main id="main-content">
  <!-- Page content -->
</main>

Add other layouts when multiple pages share a different structure that is useful to define once.

Pages

src/pages/

Files in src/pages/ define the site’s routes.

For example:

src/pages/about.astro

creates the /about/ page.

The starter uses trailing slashes consistently for internal page URLs:

/about/
/contact/

A page can compose layouts and components as needed. Repeated page structures can be moved into a layout or component when useful.

Styles

src/styles/

Use styles for project-level global styles and design customizations.

The main stylesheet is:

src/styles/global.scss

It loads @ulubit/foundations and the starter’s project styles.

The starter currently separates its global styles into areas such as:

_base.scss
_colors.scss
_layout.scss
_typography.scss
_utilities.scss

Use the shared values and utilities provided by @ulubit/foundations where they apply. Keep project-specific styling and tokens in the project.

Component-specific styles should normally stay with the component that uses them.

Utilities

src/utils/

Use utils for shared functions that are not components.

The starter currently uses this directory for date formatting utilities.

Site configuration

src/site.config.ts

site.config.ts contains site-wide information used across the project, including:

  • production URL
  • brand information
  • default title and description
  • language and locale
  • date formatting
  • contact information
  • address
  • social profiles
  • author and developer information
  • analytics ID
  • primary navigation links

Keep shared site information here instead of duplicating the same values wherever they are needed.

Shared types

src/types.ts

Use types.ts for TypeScript types that are shared across the project.

Types that only belong to one component or feature can remain alongside the code that uses them.

Public files

public/

Use public for files that should be served without being processed by Astro.

The starter uses it for assets such as:

  • favicons
  • web app icons
  • the Open Graph image
  • site.webmanifest

Assets that should be imported and processed by Astro should normally live under src/ instead.

Project configuration

The project root contains the main configuration files for Astro, TypeScript, dependencies, and pnpm.

astro.config.mjs

Configures Astro and project-wide integrations.

The starter uses it for the production site URL, sitemap integration, fonts, development toolbar settings, and Vite configuration.

package.json

Defines the project’s dependencies, development dependencies, scripts, version, and supported Node.js version.

The standard project commands are defined here:

pnpm dev
pnpm check
pnpm build
pnpm preview

tsconfig.json

Defines the TypeScript configuration.

The starter extends Astro’s strict TypeScript configuration and provides the @/ alias for files under src/:

import Header from "@/components/Header.astro"

pnpm-workspace.yaml

Defines pnpm dependency-management policies used by the starter.

These currently include the dependencies allowed to run install or build scripts and a minimum release age for newly published packages, with UluBit packages excluded from that delay.

Adapt the structure when needed

The starter provides a useful baseline, not a requirement to preserve the same file tree in every project.

A project may need additional directories for content, data, services, integrations, or other responsibilities that do not exist in the starter. Add or reorganize structure when doing so makes the project clearer and better suited to its actual requirements.

Start with the existing structure and change it when there is a reason to.