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.