Open Development

Changelog

Follow every release of the Unchained Engine. All development happens in the open under the EUPL license.

v5.0

Breaking Changes
  • One-time re-login for v5 alpha users: tokens are now signed and checked with a default tokenVersion of 0 instead of 1. Tokens issued by earlier alphas to users without a stored tokenVersion stop working once after the upgrade; those users log in again.
  • Directors read adapters from the plugin registry only: the BaseDirector factory is removed from @unchainedshop/utils; since v5 its adapter map was never filled and every director replaced its lookups (IBaseDirector remains).
  • Plugin entry points export plugins, not adapters: the ~55 remaining raw adapter re-exports (e.g. Invoice, Stripe, GridFSAdapter) are removed, as the v5 notes below already state. Use the *Plugin export (its adapter is XPlugin.adapters[0]).
  • Plugin keys follow their adapter key: four single-adapter plugins had a plugin key that differed from their adapter key and now use the adapter key: Apple IAP (shop.unchained.apple-iap), product catalog price (shop.unchained.pricing.product-price), …
  • Package cleanup: dropped the unused multer / @fastify/multipart peers of @unchainedshop/api (and from the examples) and the unused express / fastify peers of @unchainedshop/plugins.
Full changelog on GitHub →

v4.8

  • Breaking (MCP deployments): MCP migrated to the MCP TypeScript SDK v2 — the optional peer dependency is renamed from @modelcontextprotocol/sdk to @modelcontextprotocol/server, shrinking the installed MCP footprint from 94 packages to 3 (@unchainedshop/api).
  • Filter product-id cache overhauled (@unchainedshop/core-filters, @unchainedshop/core, @unchainedshop/api): cache rows of removed filter options are pruned; rows carry a generation derived from the filter's updated stamp so an overtaken rebuild can neither publish nor retire rows a newer generation already claimed …
  • Era-based regional tax plugins with bundled rate tables (@unchainedshop/plugins): Swiss VAT rates move out of code into ch-tax-rates.json (ESTV metadata, era history back to 2001) — also a behavior fix: 2011–2017 orders were previously priced with 2018–2023 rates.
  • graphql 17 across the workspace, executed by the graphql-js reference engine via @envelop/core's useEngine (the @graphql-tools/executor default drops schema argument defaults for unprovided variables on graphql 17); graphql-scalars v2; @unchainedshop/api now declares an explicit graphql >= 16.14 < 18 peer.
  • External dependency reduction: p-memoize + expiry-map semantics are provided by memoizeWithTTL, exported from @unchainedshop/utils (concurrent callers share the in-flight promise, TTL counts from settlement, resolved null stays cached, rejections are evicted, per-key delete()) …
Full changelog on GitHub →

v4.7

  • Server-side bulk export system. A new BULK_EXPORT worker (@unchainedshop/plugins) moves product, assortment and filter exports off the client and onto the server, generating CSV files through a configurable exporter factory.
  • User data export. A default user-export handler exports a user's orders, quotations, reviews and enrollments; the admin-ui gains a user-export flow with configurable fields.
  • Batch user lookup. @unchainedshop/core-users can now find users in batches by usernames and by emails, backing DataLoader-style resolution instead of per-user queries.
  • Bulk import now batches its payload to avoid large-payload errors, with adjusted product/assortment/filter import normalizers.
  • Fixed Stripe attempting to initialize without a configured apiToken.
Full changelog on GitHub →

v4.6

  • Added OCSF-compliant audit trail system in @unchainedshop/events for security monitoring and compliance (SOC 2, GDPR, HIPAA). Enable with UNCHAINED_AUDIT_ENABLED=true.
  • Added new demo data CLI tool (tools/demo-data-cli) for seeding development environments with realistic e-commerce data.
  • Typo fix: FULLFILLED → FULFILLED in OrderStatus and QuotationStatus enums. Update any code referencing these status values.
  • Typo fix: services.quotations.fullfillQuotation → services.quotations.fulfillQuotation. Update any code calling this service.
  • Removed Mutation.setBaseAssortment and Assortment.isBase field. Base assortment concept has been removed from the API.
Full changelog on GitHub →

v4.5

  • MongoDB peer dependency now requires version 7.x. Update mongodb to >= 7 < 8, mongodb-memory-server to >= 11 < 12, and @mongodb-js/zstd to >= 7 < 8.
  • WebAuthn implementation migrated from optional peer dependency fido2-lib to @passwordless-id/webauthn built-in. Custom WebAuthn integrations should be reviewed and tested.
Full changelog on GitHub →

v4.4

  • Improve performance of facet filtering by 2x
  • Upgrade to Zod 4
  • Improve Admin UI for ticketing and add a new "Messages" tab to the Work Queue so it's easier to track messaging based work items
  • Support for MongoDB Node.js driver 7.0
  • Inline connect-mongo including copyright due to untrusted downstream dependencies
Full changelog on GitHub →

v4.3

  • Delivery Providers now expose the pick-up locations too #656
  • Permissions have been updated with a new enrollUser permission
  • Admin UI: Now shows menu items and actions dynamically according to permissions of a user
  • Admin UI: Improved retry option
  • Node.js 25 by default in Dockerfiles
Full changelog on GitHub →

v4.2

  • Removed obsolete PickMUp delivery provider because it's not compatible anymore with the API of Migros
  • Stores Plugin now allows to set the stores without JSON.stringifying the value
  • Added various factory methods to simplify plugin development
  • Added two new actions viewWorkQueue and viewWork do better control custom ACL cases
  • Started to harmonize actions with admin ui permission checker
Full changelog on GitHub →

v4.1

  • Add warehousing provider loader and slightly improve performance when warehousing is involved (for ex. delivery estimations on many products)
  • Fix a case where the expiry of the enrollment was calculated wrongly
  • Fix catalog price calculation bug with leveled prices #670
  • Fix unchained supporting ai@5.0.80+ (breaking change with experimental feature)
Full changelog on GitHub →

v4.0

"Tell"
  • Only users with admin role can access the MCP server.
  • We will bring more tools to the table with upcoming minor releases, currently only basic product management is enabled
  • Bulk Import: BulkImportOperation type moved from @unchainedshop/platform to @unchainedshop/core and now requires a generic type parameter.
  • Removed CARD type for payments. We never used it and it doesn't make sense to provide card data in plaintext. Removing Mutation.updateOrderPaymentCard.
  • Query.eventsCount and Query.events now accept a DateFilterInput (start/end range) for the created date.
Full changelog on GitHub →

v3.1

  • Platform: Add OIDC Connect Support to Admin UI with singleSignOnURL configurability
  • Platform: Improve Typing for Boot Code
  • API: Expose externalLinks and singleSignOnURL in ShopInfo
  • Logger: Reducing Logging to show important events only
  • Plugins: Update Stripe
Full changelog on GitHub →

v3.0

"Odi"
  • Unchained Engine is 100% ESM and self-hosted
  • Unchained Engine loves WebCrypto, Fetch API, WebPush, URL, WebAuthn, oAuth
  • Unchained Engine runs on Bun, Node.js and Serverless frameworks.
  • Unchained Engine doesn't use ORM systems; can leverage the db driver to it's fullest potential 😉
  • Unchained Engine hates federated graphs; is fast 😉
Full changelog on GitHub →

v2.14

  • API: Extend Mutation.confirmOrder and Mutation.rejectOrder with a comment field. Allows to provide arbitrary data like a rejection reason that you can use in messaging.
  • API: Change argument format of Query.workStatistics, Query.eventStatistics & Query.orderStatistics from from/to to dateRange of type DateFilterInput
  • API: Product.simulatedPrice now accepts an optional configuration so you can also provide arbitrary configs to simulate prices
  • API: New Queries have been added to gather basic statistical data: Query.eventStatistics, Query.orderStatistics, Query.workStatistics.
  • API: Add Mutation.invalidateToken to manually mark a token as invalidated
Full changelog on GitHub →

v2.13

  • Add Query.validateVerifyEmailToken that can be used to verify if a token is valid for use when verifying email
  • Add Query.validateResetPasswordToken that can be used to verify if a token is valid for use on password reset request
  • Added Payrexx plugin
  • Allow CORS for upload handling
  • Fix avatar upload in PUT mode
Full changelog on GitHub →

v2.7

  • Improve discount types
  • Extend the functionality of the default product-discount plugin so it's universally usable for different kind of product discounts
  • Fix a case with order-discount and order-items-discount plugins not appropriately applying a rate to payment and delivery fees
Full changelog on GitHub →

v2.6

  • Add shop.unchained.pricing.order-round order price rounding plugin
  • Remove obsolete internal addRoles from users
  • Utility functions have been moved generateDbFilterById, buildSortOptions and generateDbObjectId from @unchainedshop/utils to @unchainedshop/mongodb;
  • Remove events PRODUCT_UPDATE_VARIATION_TEXTS, PRODUCT_UPDATE_TEXTS, FILTER_UPDATE_TEXTS, ASSORTMENT_UPDATE_TEXTS (triggered for every product when text changes)
  • Add new events PRODUCT_UPDATE_VARIATION_TEXT, PRODUCT_UPDATE_TEXT, FILTER_UPDATE_TEXT, ASSORTMENT_UPDATE_TEXT (triggered for every locale & product when text changes).
Full changelog on GitHub →

v2.5

  • Allow to configure an "environment" for stripe which allows to drop events coming to the the engine that are intended to land on another engine not causing false negatives in webhooks.
  • Add Error Report job that sends failed work items to an E-Mail Address of choice defined by EMAIL_ERROR_REPORT_RECIPIENT
  • Add support for net and gross calculation on order items and order totals: Added useNetPrice parameter to OrderItem.total, OrderItem.unitPrice, Order.total
  • Add granular permissions and default allow rules for all mutations even the anonymous ones
  • Add Mutation.stopImpersonation that will end an impersonated user account session and return back to the initial impersonator account.
Full changelog on GitHub →

v2.3

  • Remove renderMjmlToHtml convenience method and pre-defined html templates because mjml is too heavy weight as a dependency and html e-mails cause more issues than they solve.
  • Support MINIO_UPLOAD_PREFIX to specifiy subdirectory in bucket in front of all uploads
  • Remove various dependencies from core packages.
  • Make updating of token ownerships more performant
  • Improve pricing types
Full changelog on GitHub →

v2.2

  • Extended the input fn option of auto-scheduling input to expect a promise and also take the pre-calculated workData as input extending the possibilities to alter auto-scheduling behavior. #588
  • Remove autoSchedulingInput because there is no obvious way this is helpful and it has never been used in known projects
  • Move some platform types to platform package
  • The platform option workQueueOptions has been extended to take a retryInput. The retryInput fn can be used to alter input into work when the work is beeing retried. This allows stopping retries. #588
  • Fix timeout field in worker's and types
Full changelog on GitHub →

v2.1

  • Add Mutation.processNextWork to help trigger work from outside and removed Mutation.doWork (was not functional)
  • Customize the Cookie Path with UNCHAINED_COOKIE_PATH
  • Better Order Numbers with Hashid's that don't contain competitive 1,l,0 (O was already removed before)
  • Improved logging for the work the queue
  • Re-introducded corsOrigins adjustable through connectPlatformToExpress4
Full changelog on GitHub →

v2.0

"Federer"
  • Tags are now always LowerCase and use an own scalar
  • Order.documents has been removed because it was not used since 3 years
  • New built-in support for two standard W3C API's: Web Authentication API, Push API
  • New Web3 Experimantal Features: NFT/Token Minting Plugins, Web3 Login through Metamask
  • Unchained now uses Apollo Server 4.
Full changelog on GitHub →

v1.2

  • disableEmailInterception is not available as option anymore, but you can still disable interception in development setting the environment variable UNCHAINED_DISABLE_EMAIL_INTERCEPTION
  • All atmosphere packages have been transformed to npm packages, all plugins are now in a separate package @unchainedshop/plugins. Check out the kitchensink's boot.ts to see how to load them.
  • Boilerplate has been removed because it was very outdated. A new create-unchained-app version which supports the kitchensink will follow suit.
  • Controlpanel has been removed because Admin UI is not on-par and can be used by anyone through the new Sandbox App https://sandbox-v3.unchained.shop
  • [api] Add sort params to Query.orders, Query.quotations, User.orders, User.enrollments, User.quotations
Full changelog on GitHub →

v1.1

  • [core] Instead of updateDelivery and updatePayment we now have updateContext methods on order.delivery and order.payment modules respectively, consistent with the rest of the system.
  • [core] Discount actions in adapter and director now return a Promise to extend the possibility for discount plugins to do async work
  • [api] customFields has been removed from the input field UserProfileInput and custom data has been moved internally on the user entity from user.profile.customFields to user.meta
  • [api] A new input field sort has been added to many generel queries that return lists of something, for ex. Query.products
  • [api] A new input field queryString has been added to many generel queries that return lists of something, with this change it's possible to search for an order number through Query.orders for ex.
Full changelog on GitHub →

v1.0

"Maiglöggli"
  • Unchained 2.0 (End of 2022): Complete Meteor-free and pure ESM-only version of Unchained Engine that runs on edge frameworks.
  • [core] We have removed the Matomo tracker because it was not a plugin but rather an example of an event tracking implementation, it will be re-added later to a "recipes" docs page
  • [core] UNCHAINED_INVALIDATE_PROVIDERS has been removed in order for an inverted UNCHAINED_DISABLE_PROVIDER_INVALIDATION
  • [core] Upgrade to new GraphQL multi-part standard with graphql-upload pinning to v12, please use the latest graphql-upload-client
  • [core] Environment variables LANG, COUNTRY & CURRENCY have to be prefixed with UNCHAINED_ to prevent a conflict that may occur with other systems environment variables.
Full changelog on GitHub →

Want to Shape the Future?

Unchained is open source. Contribute features, report issues, or join the discussion.

EUPL LicensedOpen SourceCommunity Driven