Download Latest Version v2.9.0 source code.zip (45.0 MB)
Email in envelope

Get an email when there's a new version of Medusa.js

Home / v2.8.5
Name Modified Size InfoDownloads / Week
Parent folder
README.md 2025-06-25 15.2 kB
v2.8.5_ Tax-inclusive Promotions, Improved Product Imports, and Faster Application Startup source code.tar.gz 2025-06-25 20.8 MB
v2.8.5_ Tax-inclusive Promotions, Improved Product Imports, and Faster Application Startup source code.zip 2025-06-25 35.4 MB
Totals: 3 Items   56.3 MB 0

Highlights

Improved Product Imports

This release overhauls the bulk import process to make it more performant and include strict validations to catch formatting issues or typos during the pre-processing phase.

Import phases

A CSV file with products to import goes through the following two phases.

  • Pre-processing: In the pre-processing phase, we validate the contents of the entire file, check for typos, unknown columns, invalid data types, or missing values, and report errors as soon as you upload the file.
  • Importing: Products are imported in the background (as it could be time-consuming with large product catalogs). Since the validations have already been performed during the pre-processing phase, the chances of failure during the import phase are rare. However, certain database constraints around duplicate data might result in a failure.

Changes to import template

Earlier, the import template (downloaded from the admin dashboard) was out of sync with our documentation and supported many columns that were part of Medusa V1.

However, now the import template strictly allows the columns mentioned in the documentation, and an error will be raised if an unknown column is specified in the CSV file.

Performance improvements

The following changes have been made to the internals to improve the import performance and memory consumption.

  • Use S3 direct uploads instead of self-importing and storing huge CSV files on a Medusa server. For this, you must configure the S3 file provider in production.
  • Read the CSV contents as a stream of chunks and process/validate 1000 rows at a time. As a result, we never read or process the entire CSV file in memory. From our tests, this led to a memory drop from 4GB to 500MB when processing a file with 62000 rows.

Tax-inclusive Promotions

This release introduces an option to specify if fixed promotions take effect before or after taxes. Up until now, fixed promotions would always be applied before taxes, which could lead to unexpected total calculations in scenarios where pricing was otherwise tax-inclusive.

For example, consider a fixed promotion with a value of $10 applied to a tax-inclusive cart of $100 in a tax region with a 25% tax rate.

Before promotion is applied:

  • Cart total (tax-inclusive) -> $100 ($80 ex. 25% VAT)

After promotion is applied:

  • Cart total (tax-inclusive) -> $87.5 ($70 ex. 25% VAT)

As you can see, the cart is reduced by $12.5 even though the promotion value was $10. The calculation we used to perform to find the promotion adjustment was:

const adjustmentTotal = (cartWithoutTax - promotion.value) * (1 + tax_rate)

In our example, this would be:

const adjustmentTotal = (80 - 10) * (1.25) = 87.5

In this release, we updated this calculation to ensure the correct adjustment total. It looks as follows:

const adjustmentTotal = (cartWithoutTax - (promotion.value / 1 + tax_rate)) * (1 + tax_rate)

In our example, this would be:

const adjustmentTotal = (80 - 8) * (1.25) = 90

The tax-inclusivity option on a promotion is part of the promotion creation flow in the admin dashboard.

Improved application startup time

This release reduces application startup time by around ~75%. For example, on Medusa Cloud, the startup time for a relatively simple Medusa application has gone from 20 seconds to around 4 seconds. This improvement comes from parallelizing the bootstrapping of modules. Modules are strictly independent from each other, so this should have no side effects.

Querying deleted records

This release fixes issues with querying for deleted database records.

Up until now, filtering data by providing any value to the deleted_at filter would be treated as if you wanted to fetch deleted records.

For example:

:::ts
const { data } = await query.graph({
  entity: "product",
  filters: { deleted_at: { $eq: null } }
})

In this query request, we are asking for all non-deleted records; however, we mistakenly assumed that any deleted_at filter would always be filtering for deleted records, so in this case, the result set would contain deleted records.

In this release, we remove the autodetection mechanism in favor of an explicit flag withDeleted.

To query deleted records, you now need to pass the flag to the request:

:::ts
const { data } = await query.graph({
  entity: "product",
  filters: { deleted_at: { "<some timestamp>" } }
  withDeleted: true
})

Features

Bugs

Documentation

Chores

Other Changes

New Contributors

Full Changelog: https://github.com/medusajs/medusa/compare/v2.8.4...v2.8.5

Source: README.md, updated 2025-06-25