Parastore: an isometric LLM sandbox for synthetic shoppers
Draw a store, generate LLM personas, and watch them shop — an isometric 3D sandbox for synthetic-consumer experiments.
At a glance
- What is it?
- Parastore is a TypeScript and Python prototype that generates LLM personas and walks them through a drawn store layout. It is a sketch for layout comparisons, not a forecasting tool, and the README says so.
- Who is it for?
- Adopt Parastore if you want a working reference for wiring LLM personas into a spatial simulation, or a cheap way to compare two aisle layouts before moving real shelves. Skip it if you need sales forecasts you can defend: the README states there is no ground-truth calibration, persona generation costs hundreds of LLM calls for a modest store, and the published accuracy figures come from Intellicia's own synthetic consumers rather than the synthesis method in this repository.
- 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 133 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Parastore is for, and who it is actually for
Intellicia builds tooling around synthetic consumers, virtual personas generated by LLMs that the company runs surveys against instead of, or alongside, real respondents. Parastore takes that idea into physical retail. The question the README poses is direct: if a synthetic shopper can answer a survey question, can it also walk through a store, pick things up, and pay for them?
The people who benefit are not retail analysts looking for a forecast. They are engineers and researchers who want a concrete example of an LLM-driven agent simulation wired end to end, with a 3D front end, a pathfinding layer and a FastAPI backend in one repository. The README frames the project as a sketch, and calls it a prototype rather than a production forecasting tool. It also lists what a serious offline-sales model would need: POS history, real foot-traffic data, SKU-level taxonomies, weather and seasonality signals, queueing dynamics. None of that is wired up here.
The use cases the README names are comparative rather than predictive: A/B testing aisle structures and entry points, testing product placement and conversion, and prototyping layouts for acquisitions or remodels. All three are about comparing variants of a store you draw yourself.
How the persona pipeline and the simulation loop fit together
The architecture splits cleanly into a Python backend and a React front end. The backend is Python 3.13 with FastAPI, Pydantic, LiteLLM, Instructor, pathfinding, pandas and openpyxl. The front end is React 19 with Vite, TypeScript, React Three Fiber for the isometric view, TanStack Router and Query, Zustand, Tailwind v4, shadcn/ui, Recharts and ExcelJS.
Persona generation is the LLM-heavy stage. You supply a real-world store address and a one-line customer-profile description. The README says the address grounds the LLM's trade-area analysis. From there the model builds a daily traffic profile for each weekday and produces individual personas for each hour of operation. Generation is batched and parallelized, and the README estimates a minute or two depending on store size and provider latency. LiteLLM sits in the middle, which is why the default model is `gemini/gemini-3.1-pro-preview` and a `GEMINI_API_KEY` works without configuration changes.
The simulation stage is spatial, not generative. Once personas exist, they walk in on a wall-clock timeline and the 3D view animates their paths in real time. Pathfinding is a listed backend dependency, so movement is computed rather than improvised by the model. Playback controls let you scrub, pause and change speed, and a live dashboard reports visitor count, conversion rate, dwell time and per-rack engagement. The split matters: the expensive, slow part happens once at generation time, and the layout comparison runs against fixed personas.
Installing Parastore and running the golden path
The requirements are Python 3.13 or newer with uv, Node 20 or newer with pnpm 10.33.0, which is pinned in `frontend/package.json`, and an LLM provider API key. The README's quick start copies the environment file and runs the dev script, which starts uvicorn on port 8000 and Vite on port 5173 together. Ctrl-C stops both.
cp backend/.env.example backend/.env # add your LLM API key — DO NOT commit real keys
./scripts/dev.shOpen `http://localhost:5173` in a browser. If you prefer to run each side separately, the backend syncs dependencies with uv and starts uvicorn with reload enabled.
cd backend
uv sync
uv run uvicorn store_emulator.server.main:app --reloadThe health endpoint is `curl http://localhost:8000/api/health`, and the interactive OpenAPI docs are at `http://localhost:8000/docs`. The front end installs with pnpm and can point at a different backend with an environment variable.
cd frontend
pnpm install
pnpm devVITE_API_URL=http://my-host:port pnpm devFor production the README gives only a front-end build step. The backend has no build step and is meant to run under a process manager.
cd frontend && pnpm buildAfter that, the golden path is five steps. Create a project with a real store address and a one-line customer profile. Trigger the persona pipeline on the second page of the wizard and wait a minute or two. Draw the layout in the isometric grid editor, placing shelves, fridges, counters, walls and entry points, and assigning product categories to each rack. Hit play and watch personas walk in on the wall-clock timeline. Then read the dashboard for visitor count, conversion rate, dwell time and per-rack engagement.
The accuracy chart and why the README undercuts it
The README shows a predicted-versus-actual chart and a table of three metrics: a Spearman correlation of 0.955 by category, a JS-Similarity of 0.802 across all 109 products, and an NDCG@all of 0.868 across the same 109 products. The comparison covers 500 real customers from a physical convenience store and 109 products.
Those numbers look strong, and the README immediately qualifies them in a note: the results were generated via Intellicia's own synthetic consumers, not the synthesis method published in this repository. That is an unusual and honest disclosure, and it should shape how you read the table. The chart validates a pipeline the company runs internally. It does not validate the persona generation code you clone. If you replace the default model, change the prompt chain or draw a different store, you are outside the configuration that produced 0.955.
The same section states there is no ground-truth calibration, and that outputs are LLM-grounded plausibility rather than validated forecasts. Treat the metrics as a demonstration that the approach can correlate with real sales in one setting, not as a property of your run.
Cost, latency and the persona cap
The README is explicit that LLM cost and latency are real. Generating a week of personas for a modest store can be hundreds of LLM calls, and you should plan your provider budget accordingly. That is the dominant operating cost of the project, and it scales with store size and hours of operation, because personas are produced per hour of operation.
There is a hard default limit: persona generation is capped at 100 per day through the `PERSONA_DAILY_CAP` environment variable. The README explains the reasoning: the goal of the simulator is to compare layout and product-placement variants, not to reproduce a real store's full foot traffic. If your experiment needs more than 100 personas in a day, you raise the cap and pay for it. If you are comparing two shelf arrangements, the cap is not the constraint, the model's per-call latency is.
Provider choice is a config edit rather than a code change. The README points at `backend/src/store_emulator/application/config.py` and says to supply the matching `*_API_KEY` for a different provider. Because LiteLLM sits underneath, the switch is mostly a model string and a key, though the README does not document which providers have been exercised.
Where Parastore is the wrong tool
The README's own limitations section is the best guide here. No ground-truth calibration means you cannot present Parastore output to a finance team as a sales forecast. The numbers are illustrative. Any decision that turns on a revenue figure, a margin figure or a staffing figure needs a different source.
The accuracy disclosure is the second boundary. The published metrics come from Intellicia's own synthetic consumers, so the repository does not ship a validated synthesis method. Reproducing the chart is not a supported workflow. The README also notes that a rigorous offline-sales model would need POS history, foot-traffic data, SKU taxonomies, weather and seasonality, and queueing dynamics, none of which are present. If your question involves queues at checkout, seasonality, or SKU-level substitution, the simulation has no input for it.
The third boundary is operational. Hundreds of LLM calls per store-week means the tool is unsuitable where you cannot send store addresses and customer-profile descriptions to an external provider. The README does not document a local-model path or a data-residency mode, so treat that as an open question before you put a real address into the wizard.
Parastore against a discrete-event simulator
The obvious alternative for retail layout work is a discrete-event or agent-based simulator such as SimPy or Mesa in Python, or a commercial pedestrian-flow package. Those tools model movement with explicit rules: a routing graph, a service-time distribution, a queue discipline. They are deterministic given a seed, cheap to run thousands of times, and their assumptions are written down in code you can audit.
Parastore's difference is that persona behaviour comes from an LLM rather than a hand-written policy. The README's premise is that a language model can produce plausible shoppers from a store address and a one-line profile, which is something a rule-based simulator cannot do without you writing the rules. That is the trade. You get behaviour you did not have to specify, at the cost of per-run expense, provider latency, and non-determinism that a seeded simulator avoids.
If your question is about queueing, throughput or capacity, a discrete-event model answers it directly and Parastore does not. If your question is what kinds of shoppers a location produces and which racks they notice, the LLM route has no equivalent in a rule-based tool. The two are complements, not substitutes.
Licence, maintenance and what an upgrade costs
Parastore is MIT licensed, with separate licence files at the repository root: `LICENSES-BACKEND.md` and `LICENSES-FRONTEND.txt` alongside the main `LICENSE`. The MIT terms cover the project's own code. The dependency licences are the ones to check before redistribution, and the split files suggest the front-end and back-end dependency sets were reviewed separately. That is not legal advice; read the files.
The repository is not archived, and the last push was on 2026-05-21. There are no retrieved releases, so there is no tagged version to pin against. Upgrading means tracking the `main` branch. The pinned `pnpm 10.33.0` in `frontend/package.json` and the Python 3.13 requirement are the two version constraints most likely to bite, because the front end pins the package manager while the backend documents a minimum interpreter version.
The operational upgrade cost is the model string. The default is `gemini/gemini-3.1-pro-preview`, and the README points at `backend/src/store_emulator/application/config.py` for provider changes. A model swap can change persona output without any code change, which means a layout comparison is only valid within one model configuration. Re-run both variants when you change the model. The README also points AI-assisted users at `USAGE.md`, which it says covers the inputs the simulation hinges on, the LLM call count for a given persona size, and silent-failure modes worth catching before triggering a run. Read that file before your first large generation.
Editorial conclusion
Adopt Parastore if you want a working reference for wiring LLM personas into a spatial simulation, or a cheap way to compare two aisle layouts before moving real shelves. Skip it if you need sales forecasts you can defend: the README states there is no ground-truth calibration, persona generation costs hundreds of LLM calls for a modest store, and the published accuracy figures come from Intellicia's own synthetic consumers rather than the synthesis method in this repository. Before you invest time, run the backend and check your provider key against the default model, then read USAGE.md for the LLM call count for your persona size and the silent-failure modes the README points to. The store you draw is the input that matters most, so verify the grid editor handles your real footprint before generating personas.
Frequently asked questions
What are the requirements to run Parastore?
The README lists Python 3.13 or newer with uv, Node 20 or newer with pnpm 10.33.0, which is pinned in frontend/package.json, and an LLM provider API key. A GEMINI_API_KEY works out of the box because the default model is gemini/gemini-3.1-pro-preview via LiteLLM.
How many LLM calls does Parastore persona generation need?
The README says generating a week of personas for a modest store can be hundreds of LLM calls, and that generation is capped at 100 personas per day by default through the PERSONA_DAILY_CAP environment variable. It points at USAGE.md for the call count for a given persona size.
Is Parastore accurate enough to forecast store sales?
No. The README states there is no ground-truth calibration and that outputs are LLM-grounded plausibility rather than validated forecasts. It also notes the published accuracy metrics were generated via Intellicia's own synthetic consumers, not the synthesis method published in the repository.
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/intellicia-public-parastore)