---
title: 'PostCSS Processor'
description: 'Process and transform CSS with the PostCSS processor plugin.'
order: 8
---

import { CodeTabs } from '@/components/code-tabs';

# PostCSS Processor

The `@ecopages/postcss-processor` package provides a PostCSS processor plugin for Ecopages that handles CSS processing and transformation. It includes built-in presets for Tailwind CSS (v3 and v4) and supports custom configurations.

## Installation

Install the package:

<CodeTabs
	name="postcss-processor-install"
	tabs={[
		{ id: 'npm', label: 'npm', code: 'npm install @ecopages/postcss-processor' },
		{ id: 'pnpm', label: 'pnpm', code: 'pnpm add @ecopages/postcss-processor' },
		{ id: 'bun', label: 'bun', code: 'bun add @ecopages/postcss-processor' },
	]}
	defaultSelectedKey="npm"
/>

## Presets

The processor comes with presets to get you started quickly with popular setups.

### Tailwind v3 Preset

This preset includes the standard Tailwind CSS v3 stack: `tailwindcss`, `tailwindcss/nesting`, `autoprefixer`, `postcss-import`, and `cssnano`.

<CodeTabs
	name="postcss-processor-tailwind-v3"
	tabs={[
		{ id: 'npm', label: 'npm', code: 'npm install -D tailwindcss@3.4.19' },
		{ id: 'pnpm', label: 'pnpm', code: 'pnpm add -D tailwindcss@3.4.19' },
		{ id: 'bun', label: 'bun', code: 'bun add -d tailwindcss@3.4.19' },
	]}
	defaultSelectedKey="npm"
/>

```typescript
import { ConfigBuilder } from '@ecopages/core/config-builder';
import { ecopagesJsxPlugin } from '@ecopages/ecopages-jsx';
import { postcssProcessorPlugin } from '@ecopages/postcss-processor';
import { tailwindV3Preset } from '@ecopages/postcss-processor/presets/tailwind-v3';

const config = await new ConfigBuilder().setProcessors([postcssProcessorPlugin(tailwindV3Preset())]).build();

export default config;
```

### Tailwind v4 Preset (Recommended)

This preset supports Tailwind CSS v4, utilizing `@tailwindcss/postcss`. It includes `autoprefixer`, `postcss-nested`, and `cssnano` by default. It also automatically handles `@reference` injection for `@apply` directives, making usage simpler in isolated component styles.

<CodeTabs
	name="postcss-processor-tailwind-v4"
	tabs={[
		{ id: 'npm', label: 'npm', code: 'npm install -D @tailwindcss/postcss tailwindcss' },
		{ id: 'pnpm', label: 'pnpm', code: 'pnpm add -D @tailwindcss/postcss tailwindcss' },
		{ id: 'bun', label: 'bun', code: 'bun add -d @tailwindcss/postcss tailwindcss' },
	]}
	defaultSelectedKey="npm"
/>

```typescript
import path from 'node:path';
import { ConfigBuilder } from '@ecopages/core/config-builder';
import { ecopagesJsxPlugin } from '@ecopages/ecopages-jsx';
import { postcssProcessorPlugin } from '@ecopages/postcss-processor';
import { tailwindV4Preset } from '@ecopages/postcss-processor/presets/tailwind-v4';

const appRoot = process.cwd();

const config = await new ConfigBuilder()
	.setProcessors([
		postcssProcessorPlugin(
			tailwindV4Preset({
				// Path to your main CSS file containing `@import "tailwindcss";`
				referencePath: path.resolve(appRoot, 'src/styles/app.css'),
			}),
		),
	])
	.setIntegrations([ecopagesJsxPlugin()])
	.build();

export default config;
```

### Browser Support

By default, the presets target a broad range of modern browsers (`>0.3%, not ie 11, not dead, not op_mini all`).

To override this, add a `browserslist` configuration to your `package.json` or create a `.browserslistrc` file in your project root. The processor will automatically detect and use your custom configuration.

## Custom Configuration

If you prefer full control or need different plugins, you can configure the processor manually.

### Using `postcss.config.js`

The plugin automatically detects and uses standard `postcss.config.{js,cjs,mjs,ts}` files from your project root. This is the most compatible way to configure PostCSS.

```javascript
// postcss.config.js
module.exports = {
	plugins: {
		'postcss-import': {},
		'tailwindcss/nesting': {},
		tailwindcss: {},
		autoprefixer: {},
		cssnano: {},
	},
};
```

Then simply add the plugin without arguments:

```typescript
// eco.config.ts
import { postcssProcessorPlugin } from '@ecopages/postcss-processor';

const config = await new ConfigBuilder().setProcessors([postcssProcessorPlugin()]).build();
```

### Manual Plugin Configuration

You can also pass options directly to the plugin factory:

```typescript
import { postcssProcessorPlugin } from '@ecopages/postcss-processor';
import myPlugin from 'postcss-my-plugin';

postcssProcessorPlugin({
	filter: /\.css$/,
	plugins: {
		'my-plugin': myPlugin(),
	},
});
```

### Advanced Configuration

For advanced use cases, you can customize the processor with transformation hooks to modify CSS before or after PostCSS processing:

```typescript
import { ConfigBuilder } from '@ecopages/core/config-builder';
import { ecopagesJsxPlugin } from '@ecopages/ecopages-jsx';
import { postcssProcessorPlugin } from '@ecopages/postcss-processor';

const config = await new ConfigBuilder()
	.setProcessors([
		postcssProcessorPlugin({
			// Define a filter for files to process (defaults to /\.css$/)
			filter: /\.css$/,
			// Provide a function to transform input before processing
			transformInput: async (css) => `/* My Custom Header */\n${css}`,
			// Provide a function to transform output after processing
			transformOutput: async (css) => css.replace('blue', 'red'),
			// Explicitly provide plugins (overrides defaults)
			plugins: {/* custom plugins */},
		}),
	])
	.setIntegrations([ecopagesJsxPlugin()])
	.build();

export default config;
```

## Using CSS Imports

To enable CSS imports in your TypeScript/JavaScript files (e.g., `import styles from './styles.css'`), you **must** add the `postcssProcessorPlugin` to your `eco.config.ts` as shown above.

This plugin registers the build-time CSS handling Ecopages uses when those imports are loaded.

```typescript
// Component.ts
import styles from './styles.css';

// styles is the processed CSS string
console.log(styles);
```

## Processing Methods

The processor also exports standalone methods if you need to process CSS programmatically:

```typescript
import { PostCssProcessor } from '@ecopages/postcss-processor';

// Process a file
const cssFromFile = await PostCssProcessor.processPath('path/to/file.css');

// Process a string
const cssString = await PostCssProcessor.processStringOrBuffer('.foo { @apply bg-red-500; }', { filePath: 'mock.css' });
```

## Error Handling

The processor includes built-in error handling:

- File not found errors are thrown with clear messages.
- Processing errors are caught and logged.
- On error (e.g., syntax error in CSS), processing methods return an empty string to prevent build crashes, while logging the error details.

## See also

- [Custom Processor](/docs/plugins/custom-processor) — authoring processors
- [Plugin Lifecycle](/docs/core/plugin-lifecycle) — when processor hooks run
