Skip to main content

Webpack S3 plugin

webpack-s3-plugin uploads your webpack build artifacts to S3 (or any S3-compatible bucket) at the end of every build. Useful for static site CI/CD.

Install

npm install --save-dev webpack-s3-plugin

Configure

webpack.config.js
const S3Plugin = require('webpack-s3-plugin');

module.exports = {
// ... your normal webpack config
plugins: [
new S3Plugin({
s3Options: {
endpoint: 'https://s3.filebase.io',
region: 'auto',
accessKeyId: process.env.FILEBASE_KEY,
secretAccessKey: process.env.FILEBASE_SECRET,
s3ForcePathStyle: true,
},
s3UploadOptions: {
Bucket: process.env.FILEBASE_BUCKET,
ACL: 'public-read',
},
directory: 'dist',
cdnizerOptions: {
// Rewrite asset URLs in HTML to point to Filebase
defaultCDNBase: `https://${process.env.FILEBASE_BUCKET}.s3.filebase.io`,
},
}),
],
};

CI/CD

Run webpack in your CI pipeline with FILEBASE_KEY, FILEBASE_SECRET, and FILEBASE_BUCKET set as secrets. Each successful build publishes new assets directly to Filebase, where they're CDN-accelerated.

For atomic deploys with cache busting, use webpack's [contenthash] filename pattern so each build produces uniquely-named files. Combined with a long Cache-Control: public, max-age=31536000, immutable on the bucket, this gives you instant rollback (re-deploy old hash) and aggressive edge caching with no invalidation needed.

Alternative: aws-cli sync

If you don't need a webpack plugin, a simple aws s3 sync step at the end of your CI build works just as well:

aws --endpoint https://s3.filebase.io s3 sync ./dist/ s3://$FILEBASE_BUCKET/ \
--acl public-read \
--cache-control "public, max-age=31536000, immutable" \
--exclude "index.html" \
--exclude "*.html"

aws --endpoint https://s3.filebase.io s3 sync ./dist/ s3://$FILEBASE_BUCKET/ \
--acl public-read \
--cache-control "public, max-age=300" \
--exclude "*" \
--include "*.html"

The two passes apply different Cache-Control policies to hashed assets vs. HTML — long for assets, short for HTML so deploys propagate quickly.

What's next