All posts
March 16, 2026·7 min read·ERPFit Team
pime-commercetypescripterpnextproduct-management
Building a PIM for Vietnamese e-commerce

Building a PIM for Vietnamese e-commerce

Why managing products in Excel doesn't scale — and how we built a Product Information Management system from scratch.

Table of Contents

When you sell 300 products on one website, spreadsheets work fine. When you sell 300 products across 5 different websites, sync with an ERP, and need to publish to Shopee, Lazada, TikTok Shop — Excel becomes a nightmare.

That's the real situation we encountered working with a distribution business in the F&B industry. 6 brands, hundreds of products, 5 brand-specific satellite websites, 1 ERP system managing inventory — and no single source of truth for product data.

The real problem isn't lack of tools

Vietnam's market has KiotViet, MISA, Haravan — all great for sales and order management. But none of them solve the product content problem: properly spelled Vietnamese product names, detailed descriptions tailored per channel, correctly sized images per marketplace, structured specifications for comparison.

Product Information Management — PIM — is the data layer between ERP (inventory, pricing, orders) and sales channels (websites, marketplaces, catalogs). PIM doesn't replace ERP or WooCommerce — it's the single source of truth for product content.

Designing data for the Vietnamese market

First challenge: i18n. Every text field — name, description, specifications — needs bilingual Vietnamese-English support right from the schema:

// Every text field stored as { vi, en }
name: { vi: "Cối xay cà phê Kinu M47", en: "Kinu M47 Hand Grinder" }
description: { vi: "...", en: "..." }

This isn't just translation. Product names on Shopee differ from names on your own website. Lazada descriptions have different character limits than TikTok Shop. The system must allow each channel to have its own content while inheriting from the PIM master record.

Pricing uses integers — VND has no decimal places. A common mistake when using foreign libraries is storing prices as floats, leading to rounding errors on large invoices.

Flexible attribute system

Every product category has unique specifications. Coffee grinders need "burr type" (burr/blade), "capacity" (grams), "body material" (steel/wood). Electric kettles need "capacity" (ml), "wattage" (W), "temperature display" (yes/no).

Instead of hardcoding each field, we built a dynamic attribute system:

  • 15+ data types: TEXT, RICHTEXT, NUMBER, BOOLEAN, DATE, SINGLE_SELECT, MULTI_SELECT, PRICE, METRIC, IMAGE, FILE, URL, TABLE
  • Attribute groups: General, Technical, Marketing, Logistics, SEO — organized by usage context
  • Product Families: Each product group (Grinder, Kettle, Scale) defines its required and optional attributes
  • Localizable + Scopable: Attributes can vary by language (vi/en) or by sales channel (website/Shopee/Lazada)

This model draws inspiration from Akeneo — the most popular open-source PIM. But Akeneo is built on PHP/Symfony, requires Elasticsearch, and has no built-in support for Southeast Asian marketplaces. We needed something lighter that runs on a $10/month VPS.

Data provenance tracking

When product data comes from multiple sources — ERP, WooCommerce, satellite websites, manufacturer sites, manual entry — the important question isn't "what's the current value" but "where did this value come from and when".

We built provenance tracking at the individual field level:

  • Every value is tagged with its source: erpnext, woocommerce, wp-satellite, scraper, manual, ai-enriched
  • Every change is recorded as a revision: old value, new value, who changed it, when
  • Deep links back to the source — click a stock value and jump directly to the ERPNext record

This might sound like overkill for an SME. But when you discover a product price is wrong on Shopee, you need to know immediately: where did this price come from? Who last updated it? Where's the correct price? Provenance answers these questions in seconds instead of hours.

ERPNext synchronization

ERPNext is the primary ERP — managing inventory, selling prices, orders. PIM doesn't replace ERPNext — it reads stock and price data from ERPNext, then adds the marketing content that ERPNext doesn't manage.

The sync process:

  1. PIM calls the ERPNext API, fetching Bin records (stock per warehouse) and Item Price (selling prices)
  2. Aggregates stock across all warehouses, infers status: IN_STOCK, LOW_STOCK (≤3), OUT_OF_STOCK
  3. Saves results to PIM with timestamps — never overwrites source data in ERPNext
  4. Logs every sync to a DataSource table — tracking successes and failures

Only products marked as SOLD with a linked ERPNext item code get synced. INFO_ONLY products (display-only, not for sale) don't need inventory.

Enrichment from manufacturer websites

Each brand has its own website with technical specifications, high-quality images, and detailed descriptions. Instead of manual copy-paste, we wrote adapters for each brand:

  • Each adapter analyzes the HTML structure of a specific website — some run Shopify, some use WordPress, some are static sites
  • Extracts specification tables, high-resolution images, JSON-LD structured data
  • Normalizes to PIM schema — specs as key-value pairs, images with alt text
  • Never auto-overwrites — scraped data enters a review queue for approval before merging

Each adapter is a separate class inheriting from BaseBrandAdapter. Adding a new brand means writing a new adapter — no changes to core logic needed.

Completeness scoring — is the product ready?

Each sales channel has different requirements. Shopee needs at minimum: name, image, category, price, stock. Your own website needs more: long description, technical specs, review articles. Lazada requires XML in a specific schema.

The completeness scoring system calculates a readiness score per product, per channel:

  • Missing Vietnamese name? Website completeness drops.
  • Missing square 1:1 image? Shopee completeness drops.
  • Everything filled? A "Ready to publish" badge appears — staff knows exactly which products need what.

This isn't a complex feature — it's counting whether required attributes have values. But the practical impact is significant: instead of asking "why isn't this product on Shopee yet?", a glance at the completeness score tells you exactly what's missing.

Technical stack

The entire system runs on TypeScript/Bun:

  • API: Hono + tRPC — end-to-end type safety from database to UI
  • Database: PostgreSQL + Prisma — schema migrations, type-safe queries
  • Admin UI: Expo (React Native for Web) — runs in browser, can build mobile apps later
  • Static sites: Astro — generates static HTML per brand site, zero JavaScript by default
  • Media: Cloudflare R2 — image storage at very low cost

Monorepo with Bun workspaces — packages split by function (@pim/db, @pim/core, @pim/shared, @pim/ui), apps split by deployment target (api, app, web). One type change in shared is immediately available in both API and UI — no package publishing or version syncing needed.

Lessons learned

Schema-first, not feature-first. We spent significant time designing the data model before writing the first line of UI code. Product, Brand, Category, Attribute, Family, Channel — each entity needs to be right from the start because migrations are expensive later.

Don't try to replace ERP. PIM manages content, ERP manages business operations. This boundary must be clear. When PIM starts managing orders or detailed inventory, it becomes a second ERP — and nobody needs two ERPs.

Provenance tracking is expensive to build but saves debugging time. When there's a data issue — wrong price, missing diacritics, broken image — knowing the source immediately means fixing it in minutes instead of spending half a day tracing back.

Completeness scoring changes how teams work. Instead of managing via manual checklists or chat reminders, everyone can see which products need what for which channel on a dashboard. It automates data quality management.

PIM isn't a glamorous product. It's infrastructure — the foundation everything else builds on. But for multi-channel e-commerce businesses in Vietnam, it's the foundation that's most critically missing.

Share:𝕏FBin