---
title: "Browser support"
description: "The Chrome 111, Edge 111, Firefox 128 and Safari 16.4 baseline and how legacy polyfills are dropped."
requested_language: ar
language: en
translation_notice: "This page isn't translated yet"
url: https://docs.systhema.app/ar/concepts/browser-support
version: unreleased (main)
docs_index: https://docs.systhema.app/ar/llms.txt
---
> This page isn't translated yet. Showing English.


Systhema's baseline is **Chrome 111+, Edge 111+, Firefox 128+ and Safari 16.4+ (iOS 16.4+)**, and the scaffolds declare it in their root `package.json`:

```json
"browserslist": ["chrome >= 111", "edge >= 111", "firefox >= 128", "safari >= 16.4"]
```

## Why this baseline

Those numbers are the union of three floors the stack already sits on, not a preference:

- **Tailwind CSS v4**, which `@systhemaui/core` requires, supports Safari 16.4, Chrome 111 and Firefox 128. It relies on `@property`, `color-mix()` and cascade layers, so below that line a Systhema site does not render correctly whatever the JavaScript is compiled for. Firefox 128 is its number, and the highest of the three.
- **Next 16's own modern target**, generated from `browserslist "baseline widely available"`: Chrome 111, Edge 111, Firefox 111, Safari 16.4.
- **Swiper 14**, which `<Carousel>` and `<GalleryWrapper>` run on: Chrome/Edge/Firefox 110, Safari 16.4. Swiper removed the code paths and feature detection for older browsers, so that is a hard floor for those two components and no build configuration brings it back.

Every other `@systhemaui/react` component is plain React and CSS and carries no floor of its own beyond what your `browserslist` compiles for.

Keeping the list at the baseline matters in both directions: a lower floor makes the build down-compile and ship polyfills for browsers the CSS never supported anyway, and a higher one drops browsers you meant to support. Declaring it also lets `withSysthema()` drop Next's own client polyfill bundle — see [Legacy polyfills](#legacy-polyfills).

## Moving an existing project onto the baseline

Existing projects are moved onto the baseline by the `raise-browserslist-to-modern-baseline` codemod, which raises any `>=` floor sitting below the line and leaves every other query shape alone. If you keep your targets in a `.browserslistrc` instead of `package.json`, raise them by hand: the codemod only reads the root `package.json`.

## Older browsers

If you need to support older browsers, pin `swiper` to `^12` in your own dependencies and accept that Tailwind v4's CSS will still not render there. Systhema does not test that combination.

## Legacy polyfills

`withSysthema()` also stops the build shipping Next's own client polyfill bundle to browsers that need none of it.

`browserslist` drives transpilation, but it does not reach everything. Next's client entry does an unconditional `require("../build/polyfills/polyfill-module")`, so that module lands in every client bundle of every Next app at any target. What it patches — `Array.prototype.at`/`.flat`/`.flatMap`, `Object.fromEntries`/`.hasOwn`, `String.prototype.trimStart`/`.trimEnd`, `Promise.prototype.finally`, `URL.canParse`, `Symbol.description` — is native in every browser at the baseline above. Lighthouse's "Avoid serving legacy JavaScript to modern browsers" audit flags it.

When your project's `browserslist` declares a `>=` floor at or above the baseline for **all four** browsers, `withSysthema()` resolves that module to an empty one, for both Turbopack and webpack, keeping any alias you configured yourself. It reads `package.json` first and `.browserslistrc` second; a project with no `browserslist`, a floor below the line, or a moving query such as `defaults` keeps Next's polyfills, because those are cases where the answer is genuinely unknown.

Measured on the Payload starter (real `next build`, Turbopack): the home page's eagerly-loaded JavaScript went 1,001,634 to 1,000,300 bytes raw and 252,334 to 251,993 brotli. Small in bytes; the point is the audit and the parse work, not the download.

Override the decision either way:

```ts title="next.config.ts"
export default withSysthema(nextConfig, { dropLegacyPolyfills: false })
```

Pass `true` to force the drop on a project that keeps its targets somewhere Systhema cannot read: a build tool's own config, an env var, a `browserslist` key in another file. Pass `false` to keep Next's polyfills whatever the targets say.

## Related

- [Next.js integration](https://docs.systhema.app/ar/nextjs.md)
- [Client and server code](https://docs.systhema.app/ar/concepts/client-and-server.md)
