Skip to content

Conversation

@amoore108
Copy link
Contributor

@amoore108 amoore108 commented Oct 23, 2025

Summary

Changes the JSX runtime/transform from classic to automatic to help enable future upgrades to the likes of Turbopack and the Next.js App Router

This is an 'under-the-hood' change with minor user-facing benefit, but allows for slightly better developer experience as it removes the need to have the /** @jsx jsx */ pragma defined at the top of components that use Emotion css styles. It also removes the need to explicitly import React and the Emotion jsx function into components.

The Babel config is also removed from the Next.js app. This hands over compliation to Next itself, meaning we leverage its built in SWC compiler to improve build and local dev speed, as well as removing dev overhead maintaining Babel configuration and its dependencies. I also observed some minor improvements to the overall size of JS transferred and decompressed in production builds.

Terminal output from starting the Next.js app should also be a lot cleaner. Babel messages are no longer there since its not being used.

Local benchmarks for Next.js app

yarn build - Compilation improvements, other steps slightly slower, but imperceptible

Before After
Screenshot 2025-11-15 at 16 08 41 514777662-aff5a042-1225-4abb-8c1b-c7c6207a7399

From first running yarn dev to rendering an article page

Before After
514779169-2c5a8155-5146-4bfd-a1d1-8140c6d2bd85 514779222-30b719ee-78c9-457f-851e-6d344cb3f900

Unit test speed improvements with next/jest:

Before After
Screenshot 2025-11-18 at 19 25 17 Screenshot 2025-11-18 at 19 25 22

Visiting http://localhost:7081/gahuza/articles/c5y51yxeg53o with yarn build + yarn start (production build)
~5% improvement on data over the wire
~8% improvement after decompression

Before After
Screenshot 2025-11-16 at 09 53 32 Screenshot 2025-11-16 at 09 53 38

Code Changes

  • Switches JSX runtime from classic to automatic in the Express app. The Next.js app does this automatically.
  • Sets importSource to @emotion/react in Express Babel and tsconfig to allow Emotion to control JSX behaviour:
    [
    '@babel/preset-react',
    { runtime: 'automatic', importSource: '@emotion/react' },
    ],

    simorgh/tsconfig.json

    Lines 17 to 18 in 7321aba

    "jsx": "preserve",
    "jsxImportSource": "@emotion/react",
  • Removes /** @jsx jsx */ pragma requirement for components styled with Emotion css function
  • Removes import of jsx from @emotion/react from all components as this is handled by importSource: @emotion/react in the Express app and compiler: { emotion: true } in the Next app
  • Removes explicit import of React from all components as this is no longer needed under the new runtime
  • Removes babel config from Next.js app, instead deferring to its built-in compiler
  • Moves OG, local data serving and status APIs back to Pages Router. Next didn't like the OG API using JSX in the App Router since we're using importSource: @emotion/react, so it assumed Emotion was used in any instance of JSX being used. Emotion isn't supported in the App Router yet. Moving this back to the Pages Router fixes this problem, so I just moved the other APIs back as well as theres no benefit having a mixed economy
  • Uses next/jest to build Jest configs in the Next app. This is required since we're now using SWC instead of Babel: https://nextjs.org/docs/pages/guides/testing/jest#manual-setup:
    const createJestConfig = nextJest({ dir: './' });
  • Uses swc-loader in Cypress instead of Babel:
    loader: 'swc-loader',
  • Flips behaviour of the Babel transform-rename-import plugin, moving it to the Express app instead of being in the Next.js app. This is more future-proof as we move page types over to Next, but also required here since we aren't using Babel in Next anymore:
    [
    'transform-rename-import',
    { original: 'next/dynamic', replacement: '@loadable/component' },
    ],

Developer Checklist

  • UX
    • UX Criteria met (visual UX & screenreader UX)
  • Accessibility
    • Accessibility Acceptance Criteria met
    • Accessibility swarm completed
    • Component Health updated
    • P1 accessibility bugs resolved
    • P2/P3 accessibility bugs planned (if not resolved)
  • Security
    • Security issues addressed
    • Threat Model updated
  • Documentation
    • Docs updated (runbook, READMEs)
  • Testing
    • Feature tested on relevant environments
  • Comms
    • Relevant parties notified of changes

Testing

  • Manual Testing required?
    • Local (Ready-For-Test, Local)
    • Test (Ready-For-Test, Test)
    • Preview (Ready-For-Test, Preview)
    • Live (Ready-For-Test, Live)
  • Manual Testing complete?
    • Local
    • Test
    • Preview
    • Live

Additional Testing Steps

  1. List the steps required to test this PR.

Useful Links

karinathomasbbc and others added 30 commits October 9, 2025 21:30
…ice added & themeProvider + (loadable) service config required
@eagerterrier eagerterrier requested a review from Copilot November 21, 2025 16:11
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the JSX runtime from classic to automatic across both Express and Next.js applications. The change removes the need for manual React imports and Emotion JSX pragmas while enabling future framework upgrades. The migration removes Babel configuration from the Next.js app in favor of the built-in SWC compiler, improving build performance and reducing maintenance overhead.

Key changes:

  • Switched JSX runtime to automatic with @emotion/react as the import source
  • Removed /** @jsx jsx */ pragmas and manual React/jsx imports from all components
  • Removed Babel configuration from Next.js app, leveraging SWC compiler instead
  • Updated type imports to use type keyword for better tree-shaking

Reviewed changes

Copilot reviewed 284 out of 876 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
babel.config.main.js Updated to use automatic JSX runtime with Emotion import source for Express app
package.json Removed @emotion/babel-preset-css-prop, added babel-plugin-transform-rename-import
Multiple component files Removed JSX pragmas and React imports, updated to automatic runtime
docs/Coding-Standards/Styles.mdx Updated documentation to reflect new JSX runtime requirements
.eslintrc.js Disabled React-in-JSX-scope ESLint rules for automatic runtime
scripts/bundleSize/bundleSizeConfig.js Updated bundle size thresholds for production builds

@pvaliani pvaliani self-requested a review November 21, 2025 16:13
@amoore108 amoore108 marked this pull request as ready for review November 24, 2025 10:10
@amoore108 amoore108 requested a review from a team as a code owner November 24, 2025 10:10
Copy link
Contributor

@pvaliani pvaliani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brilliant work on this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants