🪟 Windows TippsThe Gemini desktop app is now available for Windows(11.09.2026 um 17:06 Uhr)
⚠️ Malware / Trojaner / VirenWindows 11 just dropped the tool ransomware abused, Microsoft says don’t restore WMIC(10.09.2026 um 20:11 Uhr)
⚠️ Malware / Trojaner / VirenVorsicht: Android-Malware verschlüsselt Ihre Handys und nimmt heimlich Fotos auf(11.09.2026 um 09:35 Uhr)
🕵️ SicherheitslückenMicrosoft geht endlich eines der nervigsten Probleme von Windows 11 an(11.09.2026 um 11:58 Uhr)
💾 IT Security ToolsSysinternals Suite(11.09.2026 um 12:00 Uhr)
🕵️ SicherheitslückenDefender 0-Day ShieldBreak (CVE-2026-69414) nicht sauber gepatcht - BornCity(11.09.2026 um 12:52 Uhr)
🔧 AI Nachrichten Stealing AI Reasoning Traces(08.09.2026 um 12:20 Uhr)
🔧 AI Nachrichten AIs as Modern Genies(08.09.2026 um 19:12 Uhr)
🪟 Windows TippsThe Gemini desktop app is now available for Windows(11.09.2026 um 17:06 Uhr)
⚠️ Malware / Trojaner / VirenWindows 11 just dropped the tool ransomware abused, Microsoft says don’t restore WMIC(10.09.2026 um 20:11 Uhr)
⚠️ Malware / Trojaner / VirenVorsicht: Android-Malware verschlüsselt Ihre Handys und nimmt heimlich Fotos auf(11.09.2026 um 09:35 Uhr)
🕵️ SicherheitslückenMicrosoft geht endlich eines der nervigsten Probleme von Windows 11 an(11.09.2026 um 11:58 Uhr)
💾 IT Security ToolsSysinternals Suite(11.09.2026 um 12:00 Uhr)
🕵️ SicherheitslückenDefender 0-Day ShieldBreak (CVE-2026-69414) nicht sauber gepatcht - BornCity(11.09.2026 um 12:52 Uhr)
🔧 AI Nachrichten Stealing AI Reasoning Traces(08.09.2026 um 12:20 Uhr)
🔧 AI Nachrichten AIs as Modern Genies(08.09.2026 um 19:12 Uhr)

🔧 Programmierung 🕛 vor 1 Jahr 16 Min Lesezeit
0

Simplify Chrome Extension Development: Add React without CRA

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

to customize pages. I also wanted to use this opportunity to play around with TypeScript since I haven’t had the chance to use it in a while.



1 — Set Up the Project

Let’s kick things off by creating a new directory for our project and initializing it with npm:




CODE
mkdir ts-chrome-extension
cd ts-chrome-extension
npm init -y




2 — Let’s add TypeScript




CODE
npm install --save-dev typescript




Once installed, we need to create a TypeScript configuration file. This file will tell the TypeScript compiler how to behave. Let’s create the tsconfig.json file:




CODE
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "es2015"],
"module": "esnext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"]
}




More details on the tsconfig.json file can be found in the .



5 — The Popup Files



Since we’re not using React yet, the popup will be simple and handle basic DOM interactions.



5.1 —popup.html




CODE
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Popup</title>
</head>
<body>
<div>
<h1>Hello, Chrome Extension!</h1>
<button id="alertButton">Click me</button>
</div>
<script src="popup.js"></script>
</body>
</html>




This is a simple HTML page with a button and a script reference to popup.js (which will be bundled from popup.ts).



5.2 — popup.ts



This file will handle basic interaction for the popup:




CODE
document.addEventListener('DOMContentLoaded', () => {
const alertButton = document.getElementById('alertButton');

if (alertButton) {
alertButton.addEventListener('click', () => {
alert('Button clicked!');
});
}
});




This simple script waits for the DOM to load, then adds a click listener to the button that triggers an alert. This structure sets the foundation for the popup functionality before we add React.



6 — Compile TypeScript



Let’s compile the TypeScript files into JavaScript. Run the following command:




CODE
npx tsc




This will transpile your TypeScript files into JavaScript. The popup.ts, background.ts, and contentScript.ts will be compiled to popup.js, background.js, and contentScript.js, respectively. But since we’ll soon add Webpack to manage the bundling, this is just a temporary step.



7 — Adding webpack for Bundling



Now that we have the basic structure, we need Webpack to handle bundling all our scripts into optimized files that Chrome can load. It can handle the copying of icons, transpiling ts into js, automatically injecting script or style files and much more.



7.1 — Install Webpack and necessary loaders




CODE
npm install --save-dev webpack webpack-cli ts-loader html-webpack-plugin mini-css-extract-plugin css-loader postcss postcss-loader copy-webpack-plugin





  • webpack: The core bundler.


  • ts-loader: Transpiles TypeScript for Webpack.


  • html-webpack-plugin: Helps generate HTML files with injected script tags.


  • CSS and PostCSS Loaders: For handling CSS (we’ll use these later with Tailwind).


  • CopyWebpackPlugin: The CopyWebpackPlugin ensures that the manifest.json and any other assets (like icons) are copied from the src folder to the dist folder.

    — We define patterns, such as copying manifest.json from src/ to the root of the dist/ directory.

    — If you have icons or other assets (e.g., images, fonts), you can add similar patterns.




7.2 — Webpack Configuration



Next, we need to configure Webpack to bundle everything. Create webpack.config.js at the root of your project:




CODE
const path = require('path'); // <-- This is missing and causes the ReferenceError

const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = (env, argv) => {
const isProduction = argv.mode === 'production';

return {
entry: {
popup: './src/popup/popup.ts',
background: './src/scripts/background.ts',
contentScript: './src/scripts/contentScript.ts',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
},
resolve: {
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
new HtmlWebpackPlugin({
filename: 'popup.html',
template: 'src/popup/popup.html',
chunks: ['popup'],
}),
new CopyWebpackPlugin({
patterns: [
{ from: 'src/manifest.json', to: 'manifest.json' },
// { from: 'src/icons', to: 'icons' }, // Copy any additional assets
],
}),
],
mode: isProduction ? 'production' : 'development',
devtool: isProduction ? false : 'inline-source-map', // Disable source maps in production
};
};




Explanation:




  • Entry Points: We’ve specified the entry points for popup.ts, background.ts, and contentScript.ts.


  • Output: The bundled files will be output to the dist folder.


  • Loaders: We use ts-loader to handle TypeScript and css-loader/postcss-loader For CSS processing (later on when we introduce Tailwind CSS).


  • HtmlWebpackPlugin: This plugin automatically injects the bundled popup.js file into the popup.html file, ensuring that our scripts are correctly linked.




7.3 — Build the Extension with Webpack



Let’s bundle everything using Webpack by running:




CODE
npx webpack --mode development




This will output the bundled files into the dist directory.



If you are having issues because of the icons section, you can either remove it or put some placeholder .pngs for now.



You will have something like this





Isn’t that better?



9 — Adding React to the Popup



We’ve got a functional extension with Tailwind styling and TypeScript for some syntax niceties and early problem detection. We also even have postcss and autoprefixer, which I’ll cover in a different article. And everything works.



Imagine however you need to make the UI more complex to manage loading and unloading data, handling tabs, and showing different UI based on the user’s subscription status. We might be getting ahead of ourselves, but for the sake of this guide, let’s assume there is a reason for it and add React to solve all of these problems. In my use case I added React to handle loading a dynamic set of data (which could’ve been done as a simpler template, but in combination with color pickers and switches of the UI based



9.1 — Install React and ReactDOM




CODE
npm install react react-dom @types/react @types-react-dom




9.2 Update Webpack for React



We need to update Webpack so it can handle .tsx files (React with TypeScript). Remember, this was the main goal we set up to do.



To handle this, modify the webpack.config.js file to include React as an entry point:




CODE
entry: {
popup: './src/popup/popup.tsx', // Update this to point to the new React component
...
},
resolve: {
extensions: ['.ts', '.tsx', '.js'], // Add .tsx to resolve for React files
},
module: {
rules: [
{
test: /\.tsx?$/, // Handle both .ts and .tsx files
...




9.3 — Convert popup.ts to React



Now we’re going to convert popup.ts to a React component. Rename popup.ts to popup.tsx and update it with a basic React component:




CODE
import React from 'react';
import { createRoot } from 'react-dom/client';
import '../styles/tailwind.css';

const Popup = () => {
const handleClick = () => {
alert('Button clicked!');
};

return (
<div className="flex flex-col items-center bg-gray-100 p-4">
<h1 className="text-xl font-bold mb-4">Hello, React Chrome Extension!</h1>
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
onClick={handleClick}
>
Click me
</button>
</div>
);
};


const container = document.getElementById('root')
const root = createRoot(container as HTMLDivElement)
root.render(<Popup />);




This simple React component mirrors the functionality of the original popup.ts but uses React’s onClick event for the button.



9.4 — Update popup.html



We don’t need to change much in popup.html except ensure it has the proper div to mount our React component. Here’s the updated popup.html:




CODE
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Popup</title>
</head>
<body class="bg-gray-100 w-80">
<div id="root"></div>
</body>
</html>




9.5 — Update tsconfig.json



We need to add "jsx": "react" and "moduleResolution”: “node"to our tsconfig.json It should look like this:




CODE
  "compilerOptions": {
"target": "es5",
"lib": ["dom", "es2015"],
"module": "esnext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"jsx": "react",
"moduleResolution": "node"
},
"include": ["src/**/*"]
}




9.6 — Rebuild with Webpack



Once the changes are made, run Webpack to rebuild the extension -> npx webpack --mode development



Now, when you reload the extension in Chrome and open the popup, you should see a React-powered UI styled with Tailwind CSS.






Conclusion — Why Not Use Create-React-App?



CRA makes a lot of assumptions about how you’re building your app, bundling everything into a single page with dynamically injected JS. This approach works great for a React web app but doesn’t mesh well with Chrome extensions, which use separate HTML pages for the popup, background scripts, and sometimes even options pages.



The best parts of building without CRA? Control and learning.



You decide what gets included, how the bundling works, and how lean or rich your extension becomes.



I also believe it is a good idea to try and see how difficult something is without the library, framework, or bootstrapping helpers. It helps learn a bit more about all of the technologies that are being used indirectly and hidden from you.



If you have gotten this far, I thank you and I hope it was useful to you! Here is a cool image of a cat as a thank you!



Photo by [Humberto Arellano](https://unsplash.com/@bto16180?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Stealing AI Reasoning Traces
1 Quelle
AIs as Modern Genies
1 Quelle
Bitcoin: KI-Hacker räumen Millionen ab! Wird Künstliche Intelligenz zum Problem? - ftd.de
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Simplify Chrome Extension Development: Add React without CRA

Thematisch verwandte Begriffe: Simplify, Chrome, Extension, Development · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...