How to build an app like Fresha: salon and spa booking software breakdown
Building a custom salon and spa booking platform like Fresha costs $120,000-$180,000 and takes 12-16 weeks. Core modules are the appointment booking engine, service and staff management, client records, POS with Stripe Terminal, and an embeddable online booking widget. The primary tech stack is React, React Native, Node.js, PostgreSQL, Stripe, SendGrid, and Twilio. Salon chains with 5+ locations building custom recoup costs in 18-24 months compared to Fresha's marketplace and payment fees.
Key Takeaways
- Fresha's base booking is free, but charges 20% commission on every new client acquired through its marketplace, plus 1.29% + £0.20 per transaction through Fresha Payments. A salon processing £20K/month pays £280/month in transaction fees alone.
- A custom booking platform costs $120,000-$180,000 to build once. Salon chains with 10+ locations typically recoup that investment within 18-24 months against Fresha fees.
- The booking engine is the hardest piece: it must find time slots where the right service, the right staff member, and the right physical resource (chair or treatment room) are all free simultaneously.
- Client records -- appointment history, color formulas, skin notes, preferred stylist -- are the salon's most valuable asset. Custom software means you own that data completely, with no platform dependency.
- Automated marketing (rebooking reminders, birthday discounts, review requests) runs on customer lifecycle events, not a fixed schedule. That distinction matters for reducing churn and growing retention.
Fresha markets itself as free. The base booking tools are free. But a salon that grows its client base through the Fresha marketplace pays 20% commission on every new client it acquires there. A salon running £20,000 per month through Fresha Payments pays £280 per month in processing fees -- £3,360 per year, before marketplace commissions.
That number compounds as volume grows. For a single location, it is manageable. For a chain with 10 locations, it becomes the argument for building your own platform.
This guide covers what that build involves: the booking engine, the service and staff management, client records, POS, automated marketing, and the tech stack that holds it together. Costs run $120,000-$180,000. Timeline is 12-16 weeks.
What "a Fresha alternative" means to build
Fresha is two things most people do not separate. It is a booking platform for managing appointments, staff, and services inside a salon. It is also a consumer marketplace where potential clients find and book salons they have never used before.
The platform tools are replaceable. The availability engine, the staff schedules, the client records, the POS -- all of these can be built custom and owned outright.
The marketplace is a different question. Fresha's marketplace brings you new clients. A custom platform does not come with a built-in audience. If your salon chain relies on Fresha marketplace traffic for 40% of new bookings, custom software does not replace that marketing channel -- it replaces the operational tools while you find other acquisition channels.
Chains that build custom typically have an existing client base, use Fresha primarily for internal operations, and want to own the data and eliminate the per-transaction fees. The 18-24 month payback period assumes you are replacing Fresha Payments and operational tools, not the marketplace.
The booking engine: where it gets complicated
Every appointment booking system looks simple until you hit the constraint problem.
A service has a duration. A staff member has a schedule. A resource (chair, treatment room, nail station) has availability. The booking engine must find time slots where all three are free at the same time.
A haircut with stylist Maria takes 45 minutes. Maria works 9am-6pm with a lunch break at 1pm. Chair 3 is already reserved from 10am-11:30am for a color treatment. The engine must return available slots for Maria that do not overlap her existing appointments, her break, and that include a free chair -- in real time, with multiple clients viewing availability simultaneously.
The simultaneous viewer problem is where naive implementations break. If two clients both see 2pm as available and both start booking, only one can succeed. The correct approach is a provisional hold at the database level: when a client begins checkout for a specific time, the system creates a short-lived hold record (typically 10-12 minutes). A unique constraint on the combination of staff member, date, and time range prevents any second booking from claiming the same slot while the hold is active. If the client abandons checkout, the hold expires and the slot returns to available.
This logic lives in the database, not in application code. Application code can be bypassed under concurrency; database constraints cannot.
Additional complexity in the booking engine:
Combo services change duration and pricing. A haircut plus a blow-dry is 75 minutes, not 45 plus 30. The combination is priced differently than the components booked separately. The service catalog must support combo definitions with their own duration and pricing rules, and the booking engine must treat combos as single atomic reservations.
Not every staff member does every service. Maria does cuts and color. James does only cuts. The engine must filter available staff by service capability, not just by schedule. The client who wants balayage cannot be shown James as an option even if his calendar is open.
Buffer time between appointments is often required. A color treatment needs a 15-minute cleanup window before the chair is ready for the next client. The booking engine must pad reservations automatically.
Service menu management
A service in a salon system is not just a name and a price. It has a duration, a category (haircuts, coloring, nails, treatments), a price, and a list of staff members who can perform it. Some services require specific resources (a color treatment needs a coloring station, not just any chair).
The admin interface for service management needs to support:
Category grouping for the public-facing booking menu. Clients should see "Haircuts," "Coloring," "Nail Services," "Treatments" rather than a flat alphabetical list of 60 services.
Staff assignments per service. When a service is created or edited, the admin selects which staff members offer it. This feeds directly into the booking engine's availability filtering.
Combo service definitions. The admin selects two or more component services, and the system computes a default combined duration and price (which the admin can then override). The combo appears as a single bookable service in the public menu.
Pricing variants. Some services are priced differently based on hair length (short, medium, long). The service definition needs to support pricing tiers, and the booking flow needs to prompt the client for the relevant attribute before confirming the price.
Staff management and individual booking links
Staff management goes beyond schedules. Each staff member needs:
Working hours by day of week, plus the ability to mark exceptions (a day off, a half day, an early finish). The system generates available booking slots for clients based on these rules.
Service capability list. Linked to the service catalog so changes to service assignments update availability automatically.
Commission rates per service. When a service is completed and payment is processed, the system calculates the staff member's commission and records it against their earnings report.
Individual booking links. Clients often want to book with a specific stylist. Each staff member gets a unique booking URL that pre-selects them in the booking flow. The staff member can share this link with returning clients, and it can be used in their own social media profiles.
The individual booking link is a retention tool as much as it is a convenience feature. When a client books directly with their regular stylist, they are not discovering the salon through the marketplace -- they are returning directly, with no commission owed.
Client records: the salon's most valuable asset
Every appointment booking platform stores appointment history. What differentiates a good salon system is the richness of the client record.
A salon client record should carry: full appointment history with the specific services received and the staff member who performed them, notes added by the stylist (preferred cutting technique, scalp sensitivity, color formula used last time), products purchased at the salon, birthday and contact information, and total spend over time.
The color formula note is not a minor detail. A colorist who can pull up a client's previous formula before they arrive delivers a meaningfully better experience than one who has to start from scratch or rely on memory. That note lives in the client record, attached to the client, not to the appointment or the stylist.
Owning this data completely is one of the primary reasons salon chains build custom. With Fresha, the client data lives in Fresha's database. If you leave the platform or Fresha changes its data export policies, access becomes complicated. Custom software means the data lives in your database, accessible for marketing, analysis, and export on your schedule.
POS and checkout
The checkout flow at the end of an appointment handles more than just payment. It handles retail product sales alongside service charges, tip handling (percentage buttons plus a custom amount field), gift card redemption, loyalty point accrual, and discount codes.
The service total pulls from the completed appointment. The stylist or receptionist can add retail products (a shampoo the client asked about, a styling product the stylist recommended) during checkout. The POS needs to handle mixed carts: services plus retail, each with different tax treatment in many jurisdictions.
For in-person payments, Stripe Terminal handles card-present transactions. The salon's Stripe account connects to a physical reader (the BBPOS WisePOS E or the Stripe Reader M2 are the standard choices). The transaction flows through Stripe, with the receipt emailed or printed.
The checkout record writes back to the client's record: the appointment is marked complete, products purchased are logged, loyalty points are updated, and the staff member's commission is calculated.
Online booking widget and standalone booking page
Clients book in two places: through the salon's own website (embedded widget) and through a standalone booking page URL the salon can share in email campaigns and social profiles.
The public booking flow is intentionally simple. The client selects a service from the menu, picks a staff member (or selects "any available"), and sees available time slots. The slot selection shows a confirmation screen with service name, duration, price, staff member, and appointment time. The client enters their name, email, and phone number, and confirms.
A confirmation email goes out immediately. A reminder SMS (via Twilio) fires 24 hours before the appointment. A second reminder goes out 2 hours before. The reminder cadence is configurable per salon.
The widget embeds on any website with a script tag and an iframe. The admin panel generates the embed code. The widget inherits the salon's brand colors and can display the salon's logo.
New clients who book through the widget are attributed to the salon's own channel, not to any marketplace. That distinction matters for understanding where clients come from and what acquisition channels are working.
Automated marketing on customer lifecycle events
The difference between a marketing automation system and a scheduler is worth understanding before you build.
A scheduler fires messages on a fixed interval: every Monday, send an email to clients who haven't booked in 30 days. A lifecycle event system fires messages when a client crosses a threshold: when a specific client's last appointment date passes the 42-day mark, trigger the rebooking reminder for that client.
The lifecycle approach is more precise and feels less like a broadcast. The message arrives when it is relevant to that client, not when the scheduler runs.
Three lifecycle triggers cover most of a salon's automated marketing:
The rebooking reminder fires when a client has not rebooked within the salon's average rebooking window (configurable, typically 5-8 weeks). The message references the client's last service, the staff member, and includes a direct booking link.
The birthday discount fires 7 days before the client's birthday with a percentage discount on their next service. The discount code is generated automatically and has a 30-day expiry tied to the client's birthday month.
The review request fires 4 hours after an appointment is marked complete. It asks the client to rate their experience. If the rating is positive (4-5 stars), it prompts them to share the review on Google. If the rating is negative (1-3 stars), it routes to an internal feedback form and flags the appointment for the manager to follow up.
All three run on customer record data: last appointment date, birthday field, appointment completion status. Building this requires a background job processor (a queue like BullMQ or a simple cron against the database) that evaluates these conditions against each client record on a regular cycle.
Tech stack
The standard stack for this build:
React for the admin web application (salon-side: appointment calendar, staff management, service menu, client records, POS, reports). React Native for an optional staff mobile app (useful for stylists who need to check their schedule or view client notes on their phone). Node.js for the backend API. PostgreSQL for the primary database, with the booking engine's concurrent reservation logic handled at the database level via constraints and row-level locking.
Stripe and Stripe Terminal for payments. Stripe handles online booking deposits and automatic reminders for outstanding balances. Stripe Terminal handles in-person card-present payments at the POS. SendGrid handles transactional email (confirmations, receipts, marketing messages). Twilio handles SMS (appointment reminders, review requests).
Redis handles the availability cache. Available time slots for a given day across all staff and services are computed and cached, with cache invalidation triggered by any new booking, cancellation, or schedule change. This keeps the public booking widget fast under concurrent load without running complex availability queries on every page load.
Timeline and cost
A full build takes 12-16 weeks with a team of 5-6 engineers. Weeks 1-4 cover the database schema, booking engine, and service/staff management API. Weeks 5-8 cover the admin web application and POS. Weeks 9-12 cover the public booking widget, automated reminders, and review collection. Weeks 13-16 cover the marketing automation layer, reporting, and load testing the booking engine under concurrent reservation scenarios.
Cost runs $120,000-$180,000 depending on scope. The lower end assumes a web-only build with no React Native staff app. The higher end includes the mobile app, more sophisticated marketing automation, and multi-location support across a larger chain.
For a 10-location salon chain running £30,000 per month through Fresha Payments and acquiring a meaningful share of new clients through the marketplace, the annual Fresha cost can exceed $60,000-$80,000. At that run rate, the custom build pays for itself inside two years.
Single-location salons should not build custom. The Fresha base tier is free, the POS fees are comparable to standard Stripe rates, and the marketplace genuinely brings new clients. The math only changes at scale.
What most builds get wrong
The booking engine is where teams underestimate scope. The simultaneous booking concurrency problem is not obvious until you test under load. Build the provisional hold mechanism from the start -- retrofitting it onto an optimistic-locking-free design causes significant rework.
The client record design is where teams underestimate value. A client record with only appointment history is adequate. A client record with color formulas, stylist notes, product history, and birthday is what retains clients for years. Design the notes and history schema with care early, because retroactively adding structured note fields to client records is painful when there are 50,000 records.
The automated marketing timing is where teams underestimate complexity. A rebooking reminder that fires at 2am is ignored. A review request that fires 4 hours after a late-evening appointment hits the client at midnight. The lifecycle event processor needs to respect salon business hours and client time zones when scheduling the actual send.
Build the booking engine concurrency correctly from the start. Design the client record for richness, not just history. Time the marketing automation with care. Get those three right and the rest of the build is straightforward.
Frequently asked questions
- A custom salon and spa booking platform costs $120,000-$180,000 and takes 12-16 weeks to build. That includes the appointment booking engine, service and staff management, client records, POS with Stripe Terminal, embeddable online booking widget, automated reminders via Twilio, and a basic marketing automation layer. Salon chains with 5+ locations typically break even against Fresha fees in 18-24 months.
- Fresha charges 0% on core booking features. The costs come from two places: a 20% commission on new clients acquired through the Fresha marketplace, and a 1.29% + £0.20 processing fee per transaction through Fresha Payments. A salon processing £20,000 per month pays around £280 in payment fees, plus marketplace commissions on top. High-volume salons or chains with significant marketplace traffic pay substantially more.
- Core features: appointment booking engine with simultaneous resource/staff/service availability checking, service menu management with duration and pricing, staff schedules and individual booking links, client records with notes and history, POS with tip handling and retail product sales, Stripe Terminal for card payments, embeddable booking widget, automated SMS and email reminders, and review collection after each visit.
- React for the admin web app, React Native for an optional staff mobile app, Node.js for the backend API, PostgreSQL for the database, Stripe and Stripe Terminal for in-person and online payments, SendGrid for email, Twilio for SMS reminders and review requests, and Redis for availability slot caching to handle concurrent booking requests without conflicts.
- Build custom when you have 5+ locations paying substantial Fresha marketplace commissions, when you want full ownership of client data without platform dependency, or when your service and staff workflows are too specific for Fresha's settings. Smaller single-location salons are better served by Fresha -- the free base tier is genuinely good value for low volumes.
Ask an AI
Get an instant summary of this post from your preferred AI assistant.



