Build a project that works and lasts

Start with a clear need and one outcome. Build a first version, test it with people, then organize operation and improvement.

Jump to a section

What Hasanat provides

Use the shared foundation instead of rebuilding accounts, services, and tools for every project.

Free Hosting

Cloudflare Pages + .hasanat.dev subdomain

Shared Auth

auth.hasanat.dev works across all apps

Database

Cloudflare D1 — fast, lightweight SQL

Email

Resend with verified hasanat.dev domain

Community & Testers

Real feedback and volunteer testers

Launch & Distribution

Featured on platform and newsletter

Start with one outcome

1

Name the need

Choose a community need or write one you know

2

Build a first version

Clone the starter template from github.com/hasanat-dev/starter

3

Bring the project in

Open its workspace and name the lead and next task

4

Test and operate

Put it in front of users, then act on their feedback

From a clear brief to a working page

The hasanat-builder skill gives your coding agent a disciplined path: shape one small first outcome with you, clone the official starter, run it locally, and verify the page before adding auth, a database, or deployment.

1

Review the source

Read the skill instructions before giving them to your agent.

2

Install the skill

One command adds it to supported coding agents.

3

Use the starter prompt

Copy it as-is; the agent starts by asking what you want to build.

Complete Hasanat skill pack

Read instructions
mkdir -p .agents/skills
unzip -n hasanat-skills.skill -d .agents/skills
Version 2026.08.03.1 · verify 7 files before installing
node verify-hasanat-skills.mjs hasanat-skills.skill hasanat-skills.manifest.json

Starter prompt — ready to copy

Copy this prompt exactly as shown and paste it into your coding agent. It starts by asking what you want to build, so there is nothing to customize.

Help me start a small working Hasanat project.

Begin by asking me what I want to build. Do not ask me to rewrite or customize this prompt. After I answer, ask at most two short follow-up questions only if needed to identify:

- who the first version is for and what problem it solves;
- the one useful action the first local page should support.

Then summarize the first milestone in one sentence and continue without waiting for me to prepare a formal brief.

First, check whether all five Hasanat skills are available: hasanat-builder, hasanat-auth, hasanat-d1, hasanat-design, and hasanat-deploy. If any are missing:

1. Download the validated complete pack, manifest, and verifier from https://hasanat.dev/skills/ to a temporary directory: hasanat-skills.skill, hasanat-skills.manifest.json, and verify-hasanat-skills.mjs.
2. Run node verify-hasanat-skills.mjs hasanat-skills.skill hasanat-skills.manifest.json. Do not install the pack if verification fails. Then show me its file listing with unzip -l and confirm that it contains one directory for each of the five skills. Briefly explain that skills are instructions and scripts the coding agent will follow.
3. Ask once for approval to install the missing skills. Do not overwrite any existing skill directory.
4. After approval, create .agents/skills in the current project and extract the pack there:

mkdir -p .agents/skills
unzip -n <temporary-path>/hasanat-skills.skill -d .agents/skills

Then load and follow hasanat-builder, loading the companion skills only when you reach authentication, database, design, or deployment work.

Keep the first milestone strict: define one useful first-page outcome, clone the public official Hasanat starter over HTTPS into a new folder, install its locked dependencies, copy .env.example, start the dev server, and verify the page in a browser. Do not require GitHub login, OAuth credentials, D1, deployment, or secrets before I can see something working locally. Continue shaping and implementing the idea with me after that checkpoint.

First success checkpoint: a real page running at the local URL Astro prints. OAuth, D1, and deployment are optional later steps.

Start from Scratch

Start with the official template and get the page running locally first, then add the React 19, Tailwind CSS v4, and Cloudflare capabilities your project needs.

1 Clone the template

git clone https://github.com/hasanat-dev/starter my-app
cd my-app && npm install
cp .env.example .env

2 Start developing

npm run dev
# → http://localhost:4321

3 Configure environment

# .env
AUTH_URL=https://auth.hasanat.dev
DB=hasanat-my-app-db

4 Submit your app

When ready, submit at hasanat.dev/build/project — you'll get a subdomain and gallery listing.

↓ The sections below (Auth, Database, i18n...) apply to this path.

I Already Have an App

Have an Islamic app and want to list it on Hasanat? Welcome — you don't need to change anything in your code.

1 Submit Your App

Go to hasanat.dev/build/project and click the add button. Enter your app's name, URL, and description in Arabic and English.

2 Get a Subdomain

Pick a subdomain like myapp.hasanat.dev — we'll point it to your existing site. Your app stays on your own hosting.

3 Optional: Integrate Shared Auth

If you want your users to use the same Hasanat account, you can integrate auth.hasanat.dev. See the Authentication section below.

Using an App Builder

You don't need to write code to build on Hasanat. Use any tool you like, then submit your app:

Full IDE in the browser — build and deploy instantly

Describe your app in words, get working code

Create full web apps from text descriptions

Design React interfaces using AI

Steps

  1. 1 Build your app using any of the tools above (or any other tool)
  2. 2 Deploy your app anywhere — Replit has built-in hosting, or use Vercel, Netlify, or any platform
  3. 3 Submit your app at hasanat.dev/build/project — choose "External hosting" and enter your site URL
  4. 4 Get a .hasanat.dev subdomain pointing to your site
Tip: App builders are great for simple projects. If you need advanced features (shared auth, D1 database), you can switch to the starter template later.

Authentication

auth.hasanat.dev provides unified authentication across all Hasanat apps. Supports Google and GitHub.

Shared Cookie Mode (Cloudflare Apps)

If your app is hosted on Cloudflare Pages under .hasanat.dev, the user signs in once and the cookie works automatically.

// src/middleware.ts
import { verifySession } from "./lib/auth";

export async function onRequest(context, next) {
const user = await verifySession(context.request);
context.locals.user = user; // null if not logged in
return next();
}

Access Current User

// In any .astro page or API route
const user = (Astro.locals as any).user;

if (user) {
console.log(user.id); // unique user ID
console.log(user.name); // display name
console.log(user.email); // email
console.log(user.image); // avatar URL
}

Protected Routes

// src/pages/api/my-data.ts
export const GET: APIRoute = async ({ locals }) => {
const user = (locals as any).user;
if (!user) return new Response("Unauthorized", { status: 401 });

// user is authenticated, proceed...
};

Login Button

<!-- Redirect to auth.hasanat.dev -->
<a href="https://auth.hasanat.dev/api/auth/signin">
Sign In
</a>

Database

Cloudflare D1 — SQLite at the edge. Fast, free, and ready to use.

Basic Usage

// Access D1 binding
import { env } from "cloudflare:workers";
const db = env.DB;

// Query
const { results } = await db
.prepare("SELECT * FROM items WHERE user_id = ?")
.bind(userId)
.all();

// Insert
await db
.prepare("INSERT INTO items (name, user_id) VALUES (?, ?)")
.bind(name, userId)
.run();

Schema Conventions

CREATE TABLE items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name_ar TEXT NOT NULL, -- Arabic name
name_en TEXT, -- English (optional)
user_id TEXT, -- from auth session
status TEXT DEFAULT 'active',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

Use bilingual columns (name_ar + name_en) for any user-facing text.

Migrations

# Create a migration
npx wrangler d1 migrations create my-db add-items

# Apply locally
npx wrangler d1 migrations apply my-db --local

# Apply to production
npx wrangler d1 migrations apply my-db --remote

i18n & RTL

Hasanat supports Arabic (default) and English. All user-facing text must be translated.

Translation Files

src/i18n/
├── ar.json # Arabic translations
├── en.json # English translations
└── utils.ts # useTranslations(), getLocalizedPath()

Using Translations

// In .astro files
import { useTranslations } from "../i18n/utils";
const t = useTranslations(locale);

<h1>{t("page.title")}</h1>

Logical CSS for RTL

Use Tailwind logical properties instead of left/right to support both directions:

Don't use Use instead
ml-4ms-4
mr-4me-4
pl-4ps-4
pr-4pe-4
left-0start-0
right-0end-0
text-lefttext-start

Deployment

Deploy your app for free on Cloudflare Pages — or use any other hosting platform.

wrangler.toml

name = "my-hasanat-app"
compatibility_date = "2024-12-01"
pages_build_output_dir = "./dist"

[[d1_databases]]
binding = "DB"
database_name = "my-app-db"
database_id = "your-d1-id"

Deploy Commands

# Build
npm run build

# Deploy to Cloudflare Pages
npx wrangler pages deploy dist

# Or connect GitHub for auto-deploy
# Cloudflare Dashboard → Pages → Create → Connect to Git

Subdomain

After submitting your project through Build, you can request a subdomain like myapp.hasanat.dev. The Hasanat team reviews and sets it up for you.

Hosting Elsewhere?

You don't have to use Cloudflare. Submit your project through Build with your URL—you can get a .hasanat.dev subdomain pointing to your site.

Design System

The Hasanat visual identity: colors, fonts, and design principles.

Colors

hasanat-50

#f0fdfa

hasanat-100

#ccfbf1

hasanat-600

#0f766e

hasanat-700

#115e59

Colors are used via Tailwind CSS: bg-hasanat-600, text-hasanat-600, border-hasanat-200 etc.

Typography

Headings

font-display (Playfair Display)

Body text

System font stack (sans-serif)

Design Principles

  • Arabic-first, RTL by default
  • Islamic aesthetic: emerald/teal palette, respectful imagery
  • Clarity over decoration
  • Accessibility: focus states, contrast, screen readers
  • Full dark mode support

Feedback Widget

Drop a floating feedback button onto any website — even ones not built on Hasanat. Submissions land directly in your project's workspace.

1. Add the script

Place this just before your closing body tag. Replace YOUR_PROJECT_ID with your project's ID (find it in your project workspace).

<script src="https://hasanat.dev/widget/feedback.js"
        data-project="YOUR_PROJECT_ID" defer></script>

2. Read your feedback

Open your project's workspace and go to the Feedback panel to see everything users send. You'll also find the ready-to-copy embed snippet there, pre-filled with your project ID.

Go to my projects →