Open-source project
harryho/vue-crm avatar
harryho/vue-crm

vue-crm: an ecommerce admin demo with a real domain model and no backend

Simple reusable CRM built on Vue and Vuetify UI

600 stars226 forksVueLicense varies

At a glance

What is it?
The vue-crm project is a Vue 3 and Vuetify 4 admin interface for an ecommerce back office, with users, categories, product variants, orders, payments, shipments, a cart, checkout and inventory, all running against an in-memory repository with no server at all. It is useful as a reference implementation of admin CRUD in Vue, and useless as a starting point for a production CRM without a backend.
Who is it for?
Adopt vue-crm as a reference for how an admin back office is structured in Vue 3 with Vuetify 4 and Pinia, especially for the order status flow, the product variant model and the CRUD screens, and run it as a demo to explore the patterns. Do not adopt it as the foundation of a real CRM, because every record lives in memory and disappears on reload, and the Docker image in the repository still builds on node:12-slim while the project requires Node 22 or later.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 101 days ago.
What is it written in?
Mainly Vue, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A demo whose data layer is an in-memory repository, on purpose

The README opens with a correction to what the project is called. It describes itself as a Vue 3 and Vuetify 4 ecommerce admin demo, built on Pinia for state and a plain in-memory data layer, with no backend and no mock-service-worker or network layer required.

That last clause is the design decision that shapes everything else. The stated goal is a realistic, self-contained ecommerce admin demo, and the reason it can be self-contained is that there is no server to stand up. You clone it, install dependencies, run it, and it works.

The data layer is one file, src/data/repository.ts, described as a plain async data layer over seed data in src/data/ecommerce/. The README is explicit that there is no real backend, no mock server and no network layer at all, by design. The async part is what keeps the door open: if every read and write goes through an async repository interface, then swapping the in-memory implementation for an HTTP client is a contained change rather than a rewrite of the screens.

That is the honest way to read this repository. It is a domain model plus an admin interface, with the persistence layer stubbed out. The value is in the modelling and the screens, not in a working system.

The project description on the repository calls it a simple reusable CRM built on Vue and Vuetify UI, and the topics list pwa, typescript, vuejs, vuetify and vuex, so the tooling has moved on from the original template even though the name has not.

The domain model: users, variants, orders with a real status history

The features list reads like a specification for a real admin back office rather than a template with sample rows.

Users have full CRUD, list, create, edit and delete, and they carry addresses, matching a real User domain model. Products have full CRUD with categories, variants and stock levels, plus browse, filter, paginate and add to cart. Orders have real line items, and the important detail is the status history: pending, then paid, then shipped, then delivered, or cancelled, with dedicated actions to record a payment, record a shipment, or mark delivered.

That order flow is the most instructive part of the project, because the transitions are modelled as actions rather than as a free-text status field. Recording a payment and recording a shipment are separate operations, which is what an order system actually does, and it means the UI can enforce a sensible sequence instead of letting a user set a status to anything.

The cart and checkout flow is described as customer-facing: add products from the catalog, adjust quantities, pick the customer and shipping address, and place a real order against the in-memory data store. Placing a real order means the order appears in the admin screens that the demo also provides, so the two halves of the application are joined by the shared in-memory store.

Inventory is a stock overview across every product variant, with low and out-of-stock indicators. That granularity is a direct consequence of modelling variants rather than products, and it is where a naive admin template usually falls short.

The change log entry for July 2026 explains the scale of the rewrite. The flat Customer, Order and Product demo was replaced with a real User, Category, Product, Order, Cart, Carrier and Staff model, Cart, Checkout and Inventory were added, Orders gained a real payment, shipment and status-history flow, and a Vitest test setup was added where none existed before.

Running it locally with bun, Node 22 and Vite

The build setup requires Node 22 or later and uses bun as the package manager, with a bun.lock committed to the repository. The README notes that npm and yarn should also work if you prefer, but are not the primary supported path.

The full sequence is short:

bash
# Clone project
git clone https://github.com/harryho/vue-crm.git
cd vue-crm

# install dependencies
bun install

# serve with hot reload at localhost:5173 (Vite's default)
bun run dev

# type-check
bun run typecheck

# run the test suite
bun run test

# production build
bun run build

The package.json gives the exact commands behind those names. dev is vite, build is vue-tsc --noEmit followed by vite build, and typecheck is vue-tsc --noEmit on its own. The build script running the type check first is a small but meaningful detail: a production build fails on a type error rather than shipping it.

There are also stage and production build variants. build-stage is vue-tsc --noEmit with vite build --base=/stage/, and build-prod is the same with --base=/, so the same bundle can be deployed under a sub path or at a domain root. preview serves the built output with vite preview --port 5050.

The test setup is Vitest, with test running vitest run and test:watch running vitest. The lint script is eslint over the Vue, JavaScript and TypeScript extensions with --fix, and there is a prettier configuration and an eslint configuration file at the root.

The dependency list in package.json is where the stack becomes clear. Vue is at 3.5.39, Vuetify at 4.1.4, Pinia at 3.0.4, vue-router at 5.1.0 and Vite at 8.1.4. Around those sit vee-validate and yup for form validation, axios for HTTP, apexcharts with vue3-apexcharts for the charts, date-fns and lodash for general work, and a set of icon packages including tabler icons, remixicon, mdi and ant-design icons. The devDependencies add jsdom, which is what Vitest uses as the DOM environment for component tests.

The Docker path, and the node:12 stage that no longer matches the project

The README documents a Docker workflow in two parts. The first is a way to test a release without building an image, serving the built dist directory from an nginx container:

bash
## Run / Test release without building new image
bun run build

# Launch nginx image to test latest release
docker pull nginx:alpine
docker run -p 8080:80 -v \
    <your_aboslute_path>/dist:/usr/share/nginx/html nginx:alpine

The second is building the image itself:

bash
# Build release image
docker build . -t  vue-demo:3.0

# Launch the development image in the backgroud
docker run --rm -d --publish 8080:80  --name vd3 vue-demo:3.0

# Check the log
docker logs vd3   -f

The Dockerfile in the repository has two stages. The build stage is node:12-slim, and it copies the source, runs npm install and then npm run build -- --prod. The delivery stage is nginx:alpine, which copies the /dist directory from the build stage into the nginx html root and installs a custom config from ./config/nginx.conf.

That build stage is the problem. The project requires Node 22 or later, the package.json sets engines to node >=22.0.0, and Vite 8 is not going to run on the Node 12 runtime in that image. The Docker build as committed is stale relative to the application, and the README does not flag it.

The delivery half is fine, and it is the part worth keeping. Building a static bundle and serving it from nginx is a sensible way to host this kind of admin interface, and having the nginx configuration in the config directory means the routing base path can be set per deployment, which pairs with the build-stage and build-prod variants in package.json.

If you build your own image, the practical fix is to use a current Node base image for the build stage and keep the nginx delivery stage as it is.

The demo deployments, the older v2 branch and the project's history

There are two live demos, and both carry the same caveat in the README: the demo is just a proof of concept, it does not have a back-end API, and it does not have all the features of the master branch.

The latest demo app is hosted at vue-app-demo.harryho.org, and the previous version at vue-demo-v2.harryho.org, whose source is on a separate branch called v2-vtf2. The screenshots in the repository are split into a latest version set under screenshots/v3.5 and a previous version set, and some older screenshot references are commented out in the README, which suggests the image set has been reorganised over time.

The change log is worth reading because it explains the shape of the repository. In July 2026 the project was uplifted to Vue 3.5, Vuetify 4, Pinia 3 and Vite 8, with the full ecommerce domain model rewrite and the Vitest setup. In March 2025 the uplift to Vue 3, Vuetify 3 and Pinia was done. In December 2024 there was an uplift to Vue 3 and Vuetify 3.

Before that it was a different project. On 2 May 2020 the vuetify-ts branch was merged to master, and the whole project moved to a new technical stack with TypeScript and Vuetify 2.x. Even earlier, the history records the most interesting architectural decision: on 6 December 2018 an archived branch called json-server was created, and it was the master branch that used Json-Server as a fake API. It was replaced because of the setup and maintenance burden, and the new master stopped relying on Json-Server, keeping only a read-only fake API and all test data is rolled back after a system restart, with nothing persisted to any physical file.

That progression is instructive. The project moved from a mock HTTP server, through a read-only fake API backed by files, to the current in-memory repository, and each step removed a moving part. The last push was on 2026-07-14, and there are no GitHub releases, so the repository history rather than a tag list is the version record. The licence is not stated in the repository, which matters if you intend to reuse the code rather than read it.

Editorial conclusion

Adopt vue-crm as a reference for how an admin back office is structured in Vue 3 with Vuetify 4 and Pinia, especially for the order status flow, the product variant model and the CRUD screens, and run it as a demo to explore the patterns. Do not adopt it as the foundation of a real CRM, because every record lives in memory and disappears on reload, and the Docker image in the repository still builds on node:12-slim while the project requires Node 22 or later. Before you build on it, decide which data layer you will write against the repository interface in src/data/repository.ts, and check the Dockerfile, which still carries the older build stage.

Frequently asked questions

Does vue-crm need a backend to run?

No. All of the features run against src/data/repository.ts, a plain async data layer over seed data in src/data/ecommerce/. There is no real backend, no mock server and no network layer at all, by design, so the app runs with zero backend setup.

What is included in the vue-crm demo?

Full CRUD for users with addresses and for products with categories, variants and stock levels, orders with line items and a status timeline of pending, paid, shipped, delivered or cancelled with actions to record a payment or shipment, a cart and checkout flow, an inventory overview across product variants, and the template's dashboard widgets and charts.

How do I install and run vue-crm?

Node 22 or later is required and bun is the package manager. Clone the repository, run bun install, then bun run dev to serve with hot reload at localhost:5173, bun run typecheck, bun run test for the Vitest suite and bun run build for a production bundle.

Is the Dockerfile in vue-crm up to date?

The build stage still uses node:12-slim and runs npm run build -- --prod, while the project requires Node 22 or later and uses Vite 8, so the image build stage is stale. The delivery stage that serves the dist directory from nginx:alpine with the config from config/nginx.conf is still usable.

What does the vue-crm data model look like after the July 2026 rewrite?

The flat Customer, Order and Product demo was replaced with a real User, Category, Product, Order, Cart, Carrier and Staff model, with Cart, Checkout and Inventory added, and Orders given a payment, shipment and status-history flow. A Vitest test setup was also added where none existed before.

Official sources

  1. harryho/vue-crm on GitHub
  2. Issues
  3. README
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/harryho-vue-crm.svg)](https://hysenlabs.com/projects/harryho-vue-crm)

Was this useful?