in development · the business app is live on test data
Ýeral
Booking for any business that sells its time, from a barber’s chair to a restaurant table. “Ýer al” is Turkmen for “take a place”.


- product questions answered in a product book before the code
- 125
- components and screens in Storybook
- 105
- tests in CI, a render check of every story included
- 1,900+
- architecture decisions, each written down
- 28
Counted from the repository, its CI and the live Storybook; checked 27 Oct. Launch market: Turkmenistan, Ashgabat first.
01 · the idea
A barber, a dentist or a café takes bookings by phone. Ýeral lets clients book a place without calling, and gives the business a free workspace to run its day.
Every booking is a place: a chair, a table, a mat, a court. The category decides how a business is found and booked: by appointment, by table or by class. It launches in Turkmenistan first, in Turkmen, Russian and English, with prices in manats.


02 · one monorepo, five sites
Four apps and an API share one contract, so a change in the booking rules reaches every screen at once.
- yeral.app
The marketplace
Home, search with a map, category and business pages, booking for an appointment, a table or a class, and the client’s account.
- business.yeral.app
The business workspace
A calendar for every specialist, requests to confirm or decline, clients, services, the team and settings.
- cms.yeral.app
The CMS
For the Ýeral team: businesses, users, complaints and the category catalogue in three languages.
- api.yeral.app
The API
REST on Postgres for all of them, with its schema and documentation generated from one contract.
- storybook.yeral.app
The design system
Every component with its stories; the stories run as browser tests with axe.
03 · rules that never break
125 product questions were answered in a product book before the code, so every screen follows the same rules.
The business confirms
By default a client never sees “booked” until the business confirms; until then the request is “sent”. A business can switch on instant confirmation.
Five statuses, one meaning
Pending, Confirmed, Completed, Cancelled and No-show mean the same on the web, in the workspace and in the CMS.
A phone booking is not a new status
When the business enters a booking by phone, it’s Confirmed with a phone icon.
No city names in the copy
Everything is relative to where you are: “near me”, not a city.
Pay at the place
No online payment yet; a deposit row is already reserved in every summary.
04 · the business day

05 · built with
frontend
- React 19
- TanStack Start
- TanStack Router
- TanStack Query
- Vite 8
- Tailwind CSS 4
- Radix UI
- MapLibre GL
- use-intl
The client site renders on the server for search engines; the workspace is a single-page app. Turkmen, Russian and English from one set of messages.
backend
- Hono 4
- Zod 4
- OpenAPI
- Drizzle ORM
- Postgres 18
Own phone sign-in with SMS codes and sessions; live updates to the calendar over server-sent events.
architecture
- Turborepo
- pnpm workspaces
- Feature-Sliced Design
- shared contract and SDK
- React Compiler
The booking engine is plain TypeScript in its own package, with no framework, so it is tested on its own.
running it
- Docker Compose
- Caddy
- own server
One deployment per market: the same Docker stack moves to servers in Turkmenistan for the launch there.
quality
- Vitest
- Storybook 10
- axe
- Playwright
- Changesets
- GitHub Actions
28 architecture decisions are written down, and every pull request is reviewed before it merges.
06 · git log
- product book, done:125 questions answered before the code
- api, done:REST on Hono and Postgres, one contract for every app
- design system, done:105 components and screens in Storybook
- business app, done:calendar, requests, clients and team, on test data
- client site, in progress:search, business pages and booking, end to end
- launch, next:Ashgabat first
how it’s run
- A product book first: every rule is decided and written down before a screen is built.
- A library before our own code, and nothing more complicated than the product needs.
- Never a secret, a key or a server address in the public repository.