Project Structure and Configuration

By Syncfusion®, Inc. · Last updated

Every folder and file in an Astro project, public/ vs src/, astro.config.mjs and defineConfig(), common options, integrations and astro add, using JavaScript and TypeScript together, astro check, editor setup and the dev toolbar.

Project Structure and Configuration

  • Every Astro project has the same basic folders and files.
  • Each one has a clear job.
  • When you know the jobs, you always know where a new file should go.
  • In this lesson, you will meet every part of a project and change its settings.

Simple lesson: Astro decides a lot from where a file lives, so the right folder matters.

A Real-World Example

  • Asha's Dev Journal is growing.
  • She now has a logo, a header used on every page and a small helper that formats dates.
  • She wants to set her real web address, so links shared online are correct.
  • Each of these things belongs in a different place in the project.

Press ▶ Run. Then open the files in the explorer and see where each one lives.

What happened:

  • The page is in src/pages, so it became the home page.
  • The header is in src/components, so you can reuse it on any page.
  • The helper is a plain .ts file in src/lib.
  • The logo is in public, and the page loads it as /logo.svg.

What You Will Learn

In this lesson, you will learn:

  1. The job of every folder in an Astro project.
  2. The difference between public/ and src/.
  3. What package.json, tsconfig.json and the .astro folder do.
  4. How to change settings in astro.config.mjs.
  5. What integrations are and how to add one.
  6. How to use JavaScript and TypeScript files together.
  7. How to set up your editor and use the dev toolbar.

The Folders of a Project

src/pages

  • Pages folder = src/pages. Every .astro file here becomes a page.
  • It is the only folder Astro needs.
  • Sub-folders make longer addresses: src/pages/blog/first.astro becomes /blog/first.

Press ▶ Run, then open the page list in the address bar. Each file became one address.

  • index.astro in a folder is that folder's main page: src/pages/blog/index.astro is /blog.

src/components

  • Component = a reusable piece of a page, such as a header, a card or a button.
  • Put components in src/components.
  • Files here do not become pages. You import them into pages.

src/layouts

  • Layout = a component that gives pages a shared frame, such as the <html>, <head> and header.
  • Put them in src/layouts. You will build one in Layouts and the Document Head.

Other Folders in src

  • src/styles is a common home for global CSS files.
  • src/lib or src/utils is a common home for helper .ts or .js files.
  • src/content.config.ts describes your content collections. You will add it in Content Collections.
  • Only src/pages and src/content.config.ts have a fixed name. The other folder names are just good habits.

Simple lesson: pages go in src/pages, reusable pieces in src/components, frames in src/layouts.

public vs src

Watch the animation. Files in src/ go through Astro's build. Files in public/ are copied as they are.

Animation: files from src go through astro build and come out changed. Files from public skip the build and are copied unchanged to dist.

src/ .astro, .ts, .css

public/ logo.svg, robots.txt

astro build compiles and shrinks copied as they are

dist/ the finished site

src files are built. public files are copied unchanged.

What Goes in public/

  • public/ = files copied to the finished site without any change.
  • Use it for favicon.svg, robots.txt, fonts and files that must keep their exact name.
  • A file at public/logo.svg is served at /logo.svg.
  • Do not write /public in the path. The word public is not part of the address.

What Goes in src/

  • src/ = your source code. Astro processes every file here.
  • .astro and .ts files are compiled.
  • CSS is combined and made smaller.
  • Images in src/ can be resized and optimised. You will learn this in Images and Fonts.

Ask one question: "Must this file stay exactly as it is?" If yes, put it in public/. If Astro should process it, put it in src/.

Simple lesson: public/ is copied, src/ is built.

The Files at the Top

package.json

  • package.json = the project's ID card for npm.
  • It lists the packages the project needs, such as astro.
  • Its scripts give short names to commands: dev, build and preview.
  • npm run dev looks up dev here and runs astro dev.

tsconfig.json

  • tsconfig.json = settings for TypeScript and for your editor.
  • Every Astro project has one, even a JavaScript project.
  • It starts with "extends": "astro/tsconfigs/strict". That means "use Astro's strict settings".
  • Your editor reads it to give you hints and warnings.

The .astro Folder

  • Astro creates a hidden .astro folder when you run it.
  • It holds generated types: files Astro writes for your editor.
  • Never edit it. Astro writes it again whenever it needs to.
  • It is listed in .gitignore, so Git does not save it.

node_modules and dist

  • node_modules/ holds the downloaded packages. npm install fills it.
  • dist/ holds the built site. npm run build fills it.
  • Never edit either one by hand. Both are made by commands.

Simple lesson: you edit src/, public/ and the config files. Commands make everything else.

Configuring Astro

astro.config.mjs and defineConfig()

  • astro.config.mjs = Astro's settings file. It sits at the top of the project.
  • A new project's file is almost empty.
  • You list your settings inside defineConfig({ ... }).
  • defineConfig() changes nothing by itself. It lets your editor suggest the right option names.
// @ts-check
import { defineConfig } from "astro/config";

export default defineConfig({
  site: "https://asha.dev",
  server: { port: 3000 },
});
  • // @ts-check asks your editor to check this file, even though it is JavaScript.

Common Options

  • site = your site's real web address. Astro uses it to build full links.
  • base = a sub-folder the site lives in, such as /journal, when it is not at the root of the domain.
  • integrations = a list of add-ons. More on these below.
  • server = dev server settings, such as port.
  • vite = settings passed to Vite, the build tool Astro uses inside.

Change site in the config below and press ▶ Run. The page reads it with Astro.site.

  • Without site, Astro cannot know your domain. Full links, sitemaps and RSS feeds need it.
  • Astro.site is a URL object, or undefined when site is not set.

TypeScript Config File

  • [TS] You can name the file astro.config.ts instead. It works the same way.
  • [JS] Keep astro.config.mjs. The // @ts-check line still gives you hints.

Finding Every Option

  • The Configuration Reference in the Astro docs lists every option.
  • Each entry shows the type, the default value and an example.
  • Look there before you search a blog. The docs match your Astro version.

Simple lesson: settings live in defineConfig(). Set site early, because many features need it.

Working with Integrations

What Integrations Are

  • Integration = an add-on package that gives Astro a new skill.
  • Examples:

    • @astrojs/react lets you use React components.
    • @astrojs/mdx lets you write pages in MDX.
    • @astrojs/sitemap makes a sitemap file for search engines.
  • An integration is added to the integrations list in the config.

Adding an Integration with astro add

The easy way is one command:

npx astro add sitemap

It does three things for you:

  1. Installs the package with npm.
  2. Imports it at the top of astro.config.mjs.
  3. Adds sitemap() to the integrations list.

It shows you the change and asks before it saves it.

Manual Installation

You can do the same steps by hand:

npm install @astrojs/sitemap

Then edit the config:

import { defineConfig } from "astro/config";
import sitemap from "@astrojs/sitemap";

export default defineConfig({
  site: "https://asha.dev",
  integrations: [sitemap()],
});

Integration Options

  • Many integrations take options inside the brackets.
  • Example: sitemap({ filter: (page) => !page.includes("/drafts/") }) leaves drafts out of the sitemap.
  • Each integration's page in the docs lists its options.

Press ▶ Run. The terminal lists the integrations that the config adds.

  • On your computer, npm run build would now also write sitemap-index.xml to dist/.
  • In this lab, integrations are named in the terminal, but they do not run. The lab cannot install packages.

Official Integrations

The Astro team keeps these, and many more:

  • UI frameworks: React, Preact, Vue, Svelte, Solid, Alpine.js.
  • Adapters: Node, Vercel, Netlify, Cloudflare. You meet them in On-Demand and Mixed Rendering.
  • Other: MDX, Markdoc, sitemap, partytown.

Tailwind CSS is no longer an integration. npx astro add tailwind adds it as a Vite plugin instead. You will add it in Styling.

Simple lesson: use npx astro add <name>. It installs the package and edits the config for you.

Using JavaScript and TypeScript Together

Mixing .js and .ts Files

  • One project can hold both .js and .ts files.
  • An .astro file can import either one.
  • A .ts file can import a .js file, and the other way round.
  • You can start in JavaScript and add types later, one file at a time.

The lab below has one .js helper and one .ts helper. The page uses both.

  • greet.js is plain JavaScript.
  • readingTime.ts says its input is a string and its result is a number.
  • Astro removes the types when it builds. The browser never sees them.

[JS] Editor Hints Without TypeScript

  • Your editor still reads tsconfig.json, so it can warn about some mistakes in .js files.
  • You can add JSDoc comments to describe values without writing TypeScript:
/**
 * @param {string} name
 * @returns {string}
 */
export function greet(name) {
  return "Welcome back, " + name + "!";
}
  • JSDoc = comments that start with /** and describe a function's inputs and output.
  • It is optional. Add it when a function is used in many places.

[TS] Checking Types with astro check

  • astro dev and astro build do not check your types. They only remove them.
  • A type mistake can still reach your site.
  • Run npx astro check to check every .astro and .ts file.
  • The first time, it offers to install @astrojs/check and typescript. Say yes.
  • Add it to your build script so mistakes stop the build:
"build": "astro check && astro build"

A site that builds is not proof that its types are right. Only astro check checks them.

Simple lesson: mix .js and .ts freely. If you use types, run astro check.

Editor Setup and the Dev Toolbar

The Astro VS Code Extension

  • Install Astro from the VS Code Extensions panel. It is published by the Astro team.
  • It adds colours (syntax highlighting) for .astro files.
  • It adds IntelliSense: suggestions, errors and "go to definition" as you type.
  • Other editors, such as WebStorm, Zed and Neovim, have Astro support too.

The Prettier Plugin

  • Prettier = a tool that formats your code neatly.
  • It needs the prettier-plugin-astro package to understand .astro files.
npm install --save-dev prettier prettier-plugin-astro

The Dev Toolbar

  • When npm run dev is running, a small toolbar appears at the bottom of your page.
  • It only shows in development. Visitors never see it.
  • Its built-in apps:

    • Inspect highlights the interactive islands on the page.
    • Audit checks for common accessibility and speed problems.
    • Settings lets you hide or move the toolbar.
  • Turn it off for the whole project in the config: devToolbar: { enabled: false }.

Simple lesson: install the Astro extension first. Use the dev toolbar's Audit to catch problems early.

TL;DR

  1. src/pages = every .astro file here becomes a page.
  2. src/components = reusable pieces. src/layouts = page frames.
  3. public/ = copied as it is. Served from the site root, without /public.
  4. package.json = packages and scripts. tsconfig.json = editor and TypeScript settings.
  5. .astro/, node_modules/, dist/ = made by commands. Never edit them.
  6. astro.config.mjs = settings inside defineConfig():

    • site for full links,
    • base for a sub-folder,
    • integrations for add-ons,
    • server.port for the dev port.
  7. Integration = add-on. Add it with npx astro add <name>.
  8. astro check = the only command that checks your types.

Common mistakes

MistakeWrong ideaCorrect ideaWhat goes wrong
Writing /public/logo.svgThe folder name is part of the pathUse /logo.svgThe image does not load
Putting a component in src/pagesAny folder works for componentsComponents go in src/componentsIt becomes a page of its own
Editing files in .astro/ or dist/They are normal source filesEdit src/, then run the command againYour change is lost on the next run
Forgetting siteAstro knows the domainSet site in the configFull links, sitemap and RSS are wrong or missing
Adding an integration to the config onlyImporting is enoughInstall the package too, or use astro addThe build says it cannot find the package
Trusting astro build for typesA build checks typesRun astro checkType mistakes reach the live site

Check Yourself

Exercises

What to Remember

  • Pages in src/pages, components in src/components, layouts in src/layouts.
  • public/ is copied as it is and served from the root.
  • Settings go in astro.config.mjs inside defineConfig().
  • Set site early. Add integrations with npx astro add.
  • .js and .ts files work together. Only astro check checks types.

Next: Component Basics, where you build Asha's Header, Footer and PostCard.