Dikasir: A Laravel 13 POS with Offline Mode and WhatsApp Gateway
Aplikasi kasir (point of sales) yang dibuat menggunakan Laravel 13, Inertia 3, React 19 dan TailwindCSS
At a glance
- What is it?
- Dikasir is an open-source point of sales system built on Laravel, Inertia, and React that covers inventory, purchasing, finance, CRM, and loyalty. It stands out for its offline transaction queue and a separate Node.js WhatsApp service, but the breadth of features brings real setup complexity.
- Who is it for?
- Adopt Dikasir if you run a small to medium retail or F&B operation and need a free, self-hosted POS with multi-warehouse stock, PPN, and offline resilience. Skip it if you require a mature, supported ecosystem or lack the staff to manage a Laravel app, a Node service, and payment webhooks.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 18 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Star history
- aryadwiputra/point-of-sales386 ★ · +109
| Repository | 2026-08-26 | 2026-10-22 |
|---|---|---|
| aryadwiputra/point-of-sales | 277 | 386 |
109 Stars in the last 57 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
What Dikasir Actually Covers
Dikasir is a full point of sales application, not just a checkout screen. The README lists modules for POS transactions, inventory with multi-warehouse support, purchasing, finance, CRM, loyalty, and even observability. That is a wide net. The target user is a business that needs more than a simple cash register: one that tracks stock across warehouses, manages supplier payables, handles customer receivables, and runs promotions. The inclusion of PPN (Indonesian value-added tax) and Indonesian customer regions suggests the primary audience is Indonesian retailers, though the multi-language support (ID/EN) added in v2.3.1 broadens it. If you only need a basic cashier app, Dikasir is overkill. But if you want a single system to replace separate inventory and accounting tools, it might fit.
The Architecture: Laravel 13, Inertia, React, and a Node Sidecar
The stack is modern: Laravel 13 on the backend, Inertia 3 to glue it to React 19, and TailwindCSS for styling. The README describes a REST API under /api/v1, token-based with Sanctum, and interactive docs via Scramble. That API is not just for mobile; it exposes POS endpoints like /pos/cart and /pos/checkout, which means you could build a custom frontend. The interesting part is the WhatsApp Gateway: a separate Node.js service in whatsapp-service/ that uses whatsapp-web.js. This is a sidecar process you must run alongside Laravel. It handles QR scanning and persistent sessions. This separation is a deliberate design choice, but it adds an operational dependency. You are not just deploying a PHP app; you are running a Node service that talks to a third-party messaging platform.
Getting It Running: Commands and Config Keys
The Quick Start in the README is straightforward. You clone the repo, copy .env.example to .env, run composer install and npm install, then php artisan key:generate, php artisan migrate --seed, and php artisan storage:link. You need two dev servers: npm run dev for Vite and php artisan serve for Laravel. The WhatsApp service requires its own npm install and npm start inside whatsapp-service/. There are default logins: admin at [email protected] and cashier at [email protected], both with password. Configuration is spread across docs/configuration.md, but the README gives a few key items: APP_VERSION for app versioning, tax_rate for PPN (tests fail if you set it non-zero), and APP_URL for payment webhooks. The troubleshooting section is honest about common pitfalls: stale permission cache after seeding, webhooks failing if APP_URL is localhost, and images not showing if storage:link is not run. That is the kind of practical detail you need before deployment.
Offline Mode and the Sync Question
One of the headline features is offline mode: the README says you can queue transactions when offline and sync when online. This is a significant claim for a web application. The README does not explain the mechanism: how the queue is stored, how conflicts are resolved, or what happens if two devices process the same product stock offline. That is a gap. For a cashier in a shop with flaky internet, offline mode is a lifesaver. But without details on sync semantics, you should assume it is a simple queue with last-write-wins. If your business needs strict inventory consistency across multiple offline terminals, you will need to test this carefully. The v2.1.2 release mentions 'POS Cart Fixes', which suggests the cart logic has had bugs, so do not treat offline as bulletproof.
The WhatsApp Gateway: Useful but Fragile
The WhatsApp Gateway is a differentiator. It lets you send automatic messages to customers, likely for reminders or promos. The implementation uses whatsapp-web.js, which is an unofficial library that automates a WhatsApp Web session. The README warns that you need to scan a QR code and that sessions persist, but it also lists a troubleshooting entry: 'WhatsApp terputus' (disconnected) and you must reconnect by scanning again. This is a fragile integration. WhatsApp can change its web interface at any time, breaking the library. For a business that depends on WhatsApp for customer communication, this is a risk. You are not using an official API; you are automating a consumer web app. The trade-off is cost: official WhatsApp Business APIs charge per message, while this is free. But you get what you pay for in terms of reliability.
Licensing and Maintenance Costs
The project is MIT licensed, which means you can use, modify, and distribute it freely, even commercially, as long as you include the original copyright notice. That is a low barrier to adoption. But the maintenance cost is not zero. The last push was in August 2026, and the release history shows a v2.3.1 with multi-language support and cleanup, so development is active. However, active development also means frequent changes. The README instructs contributors to branch from development and only merge to main via release branches, which is a sane workflow. For an adopter, you need to track releases and test upgrades, especially because Laravel 13 is a moving target. The documentation includes an architecture overview and a feature index, which helps, but you will still need to read the source for anything non-trivial. There is no mention of a paid support channel, so you are on your own.
The Real Alternative: A Hosted POS or a Simpler Stack
If Dikasir feels heavy, the alternative is a hosted POS like Square, Shopify POS, or a local Indonesian equivalent like Moka or Pawoon. These are closed-source, subscription-based, and they handle payment gateways, hardware, and updates for you. The difference in approach is fundamental: Dikasir gives you full control and no per-transaction fees, but you must manage the server, the Node service, and the payment webhooks. The hosted options are easier to start with but lock you into their ecosystem and recurring costs. For a business with a dedicated developer or a small IT team, Dikasir's open-source nature and MIT license are compelling. For a non-technical owner, a hosted POS is the pragmatic choice. There is also the option to use only the REST API and build your own frontend, which Dikasir explicitly supports, but that increases the initial effort.
Where Dikasir Falls Short
The biggest limitation is the lack of documented sync semantics for offline mode. The README says 'queue transaksi saat offline, sync saat online', but it does not say what happens to stock levels or cart holds during sync. If two cashiers sell the same last item offline, you could end up with negative stock. The troubleshooting section does not cover this. Another limitation is the dependency on a separate Node service for WhatsApp. That is an extra process to monitor, and whatsapp-web.js can break without warning. The README also notes that tests fail if tax_rate is not zero in Product::create, which hints that the test suite is not fully isolated from configuration. That is a warning sign for contributors but not necessarily for users. Finally, the project is clearly Indonesian-focused: the default data, the customer regions, and the PPN logic. If you operate outside Indonesia, you will need to adapt tax rules and localization yourself.
Editorial conclusion
Adopt Dikasir if you run a small to medium retail or F&B operation and need a free, self-hosted POS with multi-warehouse stock, PPN, and offline resilience. Skip it if you require a mature, supported ecosystem or lack the staff to manage a Laravel app, a Node service, and payment webhooks. Before committing, verify the database migrations run cleanly on your PHP version, confirm the WhatsApp service works with your network (it uses whatsapp-web.js, which can break when WhatsApp changes), and test the offline sync under real network loss. The project is MIT licensed, so you can fork and modify, but you inherit the maintenance burden.
Frequently asked questions
How do I install this point-of-sales system?
Clone the repository, copy .env.example to .env, then run composer install with PUPPETEER_SKIP_DOWNLOAD=true npm install, php artisan key:generate, php artisan migrate --seed and php artisan storage:link. Start everything with composer run dev and open http://localhost:8000, where a first installation redirects to /setup to create the admin account.
Does the point-of-sales system work offline?
Yes. Transactions are queued while the connection is down and synced when it returns, and IndexedDB is in the npm dependencies to hold that queue. Thermal receipt printing runs through WebUSB, at 80mm or 58mm widths.
Where is the API documentation for this point-of-sales system?
Interactive docs generated with Scramble are at /docs/api with a Try It control, and the OpenAPI spec is at /docs/api.json for Postman, OpenAPI Generator or Swagger Codegen. The base URL is https://dikasir.web.id/api/v1, and endpoints need a Sanctum bearer token except login, register and webhooks.
Why are my Midtrans or Xendit webhooks failing?
APP_URL has to be a public HTTPS URL rather than localhost, because the payment provider calls back to it. The environment file carries that warning directly, and the same value drives invoice and portal links.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/aryadwiputra-point-of-sales)Star history chart for your README
[](https://hysenlabs.com/projects/aryadwiputra-point-of-sales)