Korat
Architecture

Add-ons each shop chooses to install

A Korat business is not a fixed product with settings. It is assembled at runtime from modules, each one declaring what it claims, what it shows a customer, what tiles it adds to the owner console, and what permissions it introduces.

Modules are Korat's answer to the problem of building one app for restaurants, hotels, clinics and shops is that the honest version of it is four apps sharing a login. The dishonest version is one app with a settings screen so large that every business sees mostly things that do not apply to it. Korat takes a third route: the business type selects a module, the module builds the interface, and neither the public page nor the owner console has hardcoded knowledge of what a restaurant is.

The module contract

A module declares a fixed set of things, and the app assembles everything else from them. It gives an id; the business types it claims, which decides whether the module applies to a given shop; a label and a catalogue title; a primary call to action, the one button the customer page leads with; and a catalogue view — a menu for food, room types for stay, services for a clinic, products for retail.

Four further declarations are optional, and they are where the system earns its keep. A module may declare capabilities, which become new permissions available to staff roles; console tiles, which appear in the owner dashboard grid; a console screen of its own; and a customer-facing page section, injected into the shop's public page. A module declaring none of the four is a pure catalogue; one declaring all four reshapes both sides of the app at once.

There is also a shared UI kit — a primary CTA button, a catalogue row, a chip, a section label and an empty state — and modules are expected to build from it. Not house style for its own sake: it is what makes a separately written module look like part of the app rather than an embedded widget.

The four core modules are the business types

The four core modules are not add-ons at all; they are what a business type means. Food claims restaurant and cafe. Stay claims stay, hotel, resort, apartment, condo and village — six labels, one module, because a condo rental and a guesthouse night differ in wording, not mechanism. Service claims service and clinic, where the clinic variant relabels the interface to appointments, patients and treatment courses without forking the code. Retail claims retail.

Because these are modules rather than branches inside one giant screen, the food module's kitchen display and option groups do not exist for a hotel — not hidden behind a flag, not disabled, absent. The surface area a shop sees is a function of what it declared itself to be.

Seven installable add-ons, and they work for any type

On top of the core modules sit seven add-ons, all of which apply regardless of business type. Team permissions is the most interesting, because it is built out of the other modules: it constructs a permission editor from every installed module's declared capabilities, so installing a new module gains its permissions in the editor without anyone updating a list.

Payment channels adds a console tile for configuring accepted channels and a customer-visible list of them on the public page — one add-on writing to both sides through two declaration slots. Memberships and subscriptions introduces plans a customer can buy directly from the shop's page. Renewal reminders handles the follow-up memberships and treatment courses create. Projects and tasks is a work board for a business: projects, tasks, assignees, statuses, comments and notifications. Materials and production is a real stock ledger: materials, receipts, adjustments, scrap, versioned bills of materials, production orders and stock counts. Automation is if-this-then-that rules a business writes itself, with a trigger and action catalogue, backtesting against past data, a dry run that writes nothing, and a ceiling on work per tick. Each of the seven is a shipped first-party module written against the same contract a third party would use — a deliberate discipline, because a contract is only real if its authors are constrained by it too.

Install and uninstall, per shop

Add-ons are managed from the Plugin Store inside the owner console, and installation is scoped to a single business. An owner running two shops can install memberships on one and not the other, and the two dashboards genuinely differ. Which add-ons a shop package already includes, and which are bought separately, is set out on the plans page; what it takes to open a shop in the first place is a name, an address and a type.

Uninstalling sits behind a confirmation, and the confirmation says something specific: the data is not deleted. This matters more than it sounds. The reason people hesitate over an uninstall button is that they assume it is destructive, so they leave modules installed that they are not using, and the console fills with tiles nobody opens. Telling them what does *not* happen is what makes the button usable. After uninstalling, the add-on contributes nothing — no tiles, no permissions in the role editor, no section on the public page — but its records survive a reinstall.

What this is not, yet

Third-party plugins are not open. The Plugin Store itself says so rather than implying otherwise through an empty "more coming" shelf. What exists today is a modular architecture with a real contract, four core modules and seven first-party add-ons written against it, all loading through the same registration path. Third-party submission is the stated next step, not a live marketplace: there is no developer portal, no review queue and no published SDK.

We describe it this way because the architecture is the interesting part and it is true today, whereas a marketplace is a claim about the future. The test of the contract is whether a module written entirely against it — tiles, capabilities and a page section, touching no core code — behaves like a native part of the app. Seven of them do. Opening that to outsiders is a policy and review problem more than a technical one, and it is not solved.

Why modules rather than feature flags

A feature flag turns something off. A module contributes something. The difference shows up in the permission editor: with flags, somebody maintains a master list of every capability and has to remember to extend it. With the contract, the Team permissions add-on asks each installed module what it declares and builds the editor from the answers, so the list cannot go stale. The same pattern applies to the dashboard grid and to the public page — none of them enumerate features, all of them ask.

It also bounds the cost of a new vertical. Adding a business type Korat does not yet serve is a module: declare the types it claims, a catalogue, a CTA, and whichever optional slots it needs — no touching the console, the page renderer or the permission system. That is what makes a super-app tractable instead of a slow accumulation of special cases.

There is no third-party plugin marketplace. Everything installable today is first-party, and the store says so in the app. Third-party submission is the stated next step — there is no developer portal and no published SDK to build against yet.

Plugin code also still ships inside the APK rather than being fetched per plugin on use. That is a known limitation and the obvious prerequisite for opening the store to anyone outside the project.

Required declarations
id · claimed business types · label · catalogue title · primary CTA · catalogue view
Optional declarations
capabilities · console tiles · console screen · customer page section
Core modules
Food · Stay · Service · Retail
Add-ons
Team permissions · Payment channels · Memberships and subscriptions · Renewal reminders · Projects and tasks · Materials and production · Automation
Install scope
per shop
Uninstall
behind a confirmation stating that data is not deleted
Third party
not open — first-party add-ons only

Frequently asked questions

Can I write a plugin for Korat?

Not yet. The module contract is real and the seven installable add-ons are written against it, but third-party submission is not open — there is no developer portal, no review process and no published SDK.

The store says this in the app rather than showing an empty shelf that implies otherwise.

What happens to my data if I uninstall an add-on?

Nothing is deleted. The confirmation dialog says so explicitly, because assuming an uninstall is destructive is the usual reason people leave modules installed that they never open.

After uninstalling, the add-on contributes no console tiles, no permissions in the role editor and no section on your public page. Reinstall it and its records are still there.

Do I have to pick one business type forever?

A module claims a set of business types, and the shop's type is what selects it. The Stay module alone claims six — stay, hotel, resort, apartment, condo and village — so the labels within a family are interchangeable.

The seven add-ons are type-independent: any business can install any of them.

How do module permissions reach the role editor?

The Team permissions add-on builds the editor by asking every installed module what capabilities it declares, rather than reading a hand-maintained master list.

That is why installing a new module immediately gives you its permissions to assign, and why the list cannot fall out of date.

Do modules look different from the rest of the app?

They should not. A shared UI kit supplies the primary CTA button, the catalogue row, the chip, the section label and the empty state, and modules build from it.

The point is that a module reads as part of the app rather than as an embedded widget with its own opinions about spacing.

See the modules working

Create a business, choose its type, and the console builds itself from whatever modules claim it.