Build from the starter
The Hasanat starter is the suggested starting point for new apps. It is a public, MIT-licensed repository set up for Arabic first and for Cloudflare.
What the starter includes
Section titled “What the starter includes”- Astro 5 with server rendering, and React 19 for interactive parts.
- Tailwind CSS v4 and strict TypeScript.
- Arabic (RTL, the default) and English.
- Ready-made integration with shared sign-in.
- Helpers for a Cloudflare D1 database and a setup for Cloudflare Pages.
- Biome for formatting and linting, zod for input validation, and lucide-react for icons.
- Four coding-agent skills in
.github/skills/. These copies are older than the skills pack; use the pack.
Requirements
Section titled “Requirements”git, Node.js 20 or newer, and npm. The starter uses npm and package-lock.json; do not switch package managers.
First run
Section titled “First run”-
Create your copy. Press Use this template on the starter’s GitHub page to create your repository, or clone it directly:
نافذة طرفيّة git clone --depth 1 https://github.com/hasanat-dev/starter.git my-appcd my-app -
Install dependencies and copy the environment file:
نافذة طرفيّة npm installcp .env.example .env -
Start the development server:
نافذة طرفيّة npm run devOpen the URL Astro prints, normally
http://localhost:4321. The root redirects to/ar/. If the port is busy, use the URL Astro picks instead of stopping another process. -
Check the build before you change anything:
نافذة طرفيّة npm run checknpm run build
The first success checkpoint is a real page running on your machine. Sign-in, a database, and deployment are later, optional steps.
Known issues in the starter
Section titled “Known issues in the starter”We tried the starter unchanged on 13 October 2026: install, build, and the development server work, but two commands fail.
-
npm run checkreports one error:Cannot find name 'D1Result'insrc/lib/db.ts. Add this line tosrc/env.d.ts, next to theD1Databasetype:type D1Result = import("@cloudflare/workers-types").D1Result; -
npm run lintstops becausebiome.jsonuses Biome 1 keys while the starter installs Biome 2.npx biome migrate --writeupdates the configuration, but some rules still flag Astro files and Tailwind syntax. Rely onnpm run checkandnpm run builduntil the starter is fixed.
Environment file
Section titled “Environment file”.env.examplehas only two variables:PUBLIC_SITE_URLandPUBLIC_APP_NAME. Shared sign-in needs no secrets.- Two commented lines,
HASANAT_CLIENT_IDandHASANAT_CLIENT_SECRET, refer to an OAuth flow for external apps. That flow does not exist today, so leave them as they are. See sign-in. - Never commit secrets or send them in a chat or a request.
Project structure
Section titled “Project structure”src/├── middleware.ts reads the sign-in session├── lib/│ ├── auth.ts sign-in and sign-out links, protected pages│ └── db.ts D1 helpers├── layouts/│ └── Layout.astro sets lang and dir├── pages/│ ├── index.astro redirects to /ar/│ ├── ar/ Arabic pages│ ├── en/ English pages│ └── api/health.ts├── i18n/ ar.json, en.json, utils.ts└── styles/global.css Tailwind colours and fontsschema.sql database schemawrangler.toml Cloudflare settings.env.example.github/skills/ coding-agent skillsAGENTS.md instructions for coding agentsDATA_POLICY.md data policy for buildersCommands
Section titled “Commands”| Command | What it does |
|---|---|
npm run dev |
Starts the development server at localhost:4321 |
npm run build |
Builds for production |
npm run preview |
Previews the build locally |
npm run lint |
Lints with Biome |
npm run check |
Runs TypeScript and Astro checks |
npm run db:migrate:local |
Applies schema.sql to the local D1 database |
npm run db:migrate:prod |
Applies it to the production database |
Before the database commands, replace YOUR_DB_NAME in package.json with your database name.
Starter conventions
Section titled “Starter conventions”From the starter’s AGENTS.md:
- Import with the
@/path alias. - Use Tailwind logical properties such as
ms-*andpe-*instead ofml-*andpr-*. - Add every user-facing string to both
ar.jsonanden.json; do not hardcode text in pages. - Biome for formatting, not Prettier; zod for input validation; lucide-react for icons.
- Do not add Firebase or another auth provider: use auth.hasanat.dev and D1.
After the first page works
Section titled “After the first page works”- Shape the first version around one useful outcome, following the spec if it is a Hasanat project.
- When you need sign-in, a database, or a subdomain, read shared services (in Arabic).
- The starter’s README points to an old submission page on hasanat.dev that is no longer the way to work. Request subdomains and listings from the platform dashboard.