npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vite-shield

v1.0.0

Published

One-click security headers for Vite/React

Readme

Vite-Shield 🛡️

One-click security headers for Vite/React applications

Automatically configure comprehensive security headers for your Vite-based React applications with a single command. Vite-Shield integrates security headers seamlessly into your development and production environments.

Features

  • Zero Configuration: Works out of the box with any Vite/React project
  • Complete Security Headers: Implements all essential security headers
  • Multi-Environment Support: Configures headers for dev, preview, and production
  • Production-Ready: Generates Express.js server and Nginx configuration
  • AST-Based: Safely modifies vite.config.ts/js using AST transformations
  • Non-Destructive: Only adds headers, doesn't modify existing configuration

Quick Start

Installation

Global installation (recommended for CLI usage):

npm install -g vite-shield

Local installation (for project-specific usage):

npm install --save-dev vite-shield

Use with npx (no installation required):

npx vite-shield

After installation, the vite-shield command will be available globally (if installed globally) or via npx vite-shield.

Usage

Navigate to your Vite/React project directory and run:

vite-shield

That's it! Vite-Shield will:

  1. ✅ Update your vite.config.ts or vite.config.js with security headers for dev and preview servers
  2. ✅ Create a production-ready server.js with Express.js and security headers
  3. ✅ Create an nginx.conf template with security headers
  4. ✅ Update your package.json with production server script and dependencies

What Gets Configured

Security Headers Applied

Vite-Shield configures the following security headers:

| Header | Value | Purpose | |--------|-------|---------| | Strict-Transport-Security | max-age=31536000; includeSubDomains; preload | Forces HTTPS connections | | X-Frame-Options | SAMEORIGIN | Prevents clickjacking attacks | | Content-Security-Policy | Comprehensive CSP policy | Controls resource loading and prevents XSS | | X-Content-Type-Options | nosniff | Prevents MIME-type sniffing | | Referrer-Policy | no-referrer | Controls referrer information | | X-DNS-Prefetch-Control | off | Disables DNS prefetching | | X-Download-Options | noopen | Prevents file execution in IE | | X-Permitted-Cross-Domain-Policies | none | Restricts cross-domain policies | | X-XSS-Protection | 0 | Disables legacy XSS filter |

Files Created/Modified

1. vite.config.ts / vite.config.js

Adds security headers to both server and preview configurations:

export default defineConfig({
  server: {
    headers: {
      'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload',
      'X-Frame-Options': 'SAMEORIGIN',
      // ... all other headers
    },
  },
  preview: {
    headers: {
      // ... same headers for preview server
    },
  },
});

2. server.js (Created)

Production-ready Express.js server with security headers:

import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';

const app = express();

// Security headers middleware
app.use((req, res, next) => {
  res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
  res.setHeader('X-Frame-Options', 'SAMEORIGIN');
  // ... all security headers
  next();
});

// Serve static files and handle SPA routing
app.use(express.static(path.join(__dirname, 'dist')));
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});

app.listen(process.env.PORT || 8080);

3. nginx.conf (Created)

Nginx configuration template with security headers:

server {
    listen 8080;
    server_name _;
    root /home/site/wwwroot;
    index index.html;

    # Security headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    # ... all other headers

    location / {
        try_files $uri /index.html;
    }
}

4. package.json (Updated)

Adds production server script and ensures dependencies:

{
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.21.2"
  },
  "type": "module"
}

How It Works

AST-Based Configuration

Vite-Shield uses jscodeshift to safely parse and modify your vite.config.ts or vite.config.js file. This ensures:

  • ✅ No syntax errors introduced
  • ✅ Preserves existing configuration
  • ✅ Handles TypeScript and JavaScript
  • ✅ Only adds headers, doesn't overwrite existing settings

Transformation Process

  1. Parse Configuration: Reads your vite.config.ts or vite.config.js
  2. Find Config Object: Locates the defineConfig call
  3. Add Headers: Safely adds headers to server and preview sections
  4. Generate Code: Outputs updated configuration with proper formatting

Production Server Generation

The generated server.js:

  • Uses ES modules (modern JavaScript)
  • Includes all security headers as middleware
  • Serves static files from dist/ directory
  • Handles SPA routing (React Router, Vue Router, etc.)
  • Ready for deployment on any Node.js hosting platform

Customization

Updating Content Security Policy

After running vite-shield, you may need to customize the Content Security Policy (CSP) based on your application's needs:

Common Customizations

Add API Endpoints:

// In server.js, update the CSP connect-src directive
connect-src 'self' https://api.example.com https://*.blob.core.windows.net wss://ws.example.com

Add External Image Sources:

// Update img-src directive
img-src 'self' data: blob: https://*.googleusercontent.com https://cdn.example.com

Add Font Sources:

// Update font-src directive
font-src 'self' data: https://fonts.gstatic.com https://cdnjs.cloudflare.com

Environment-Specific Configuration

For different CSP policies in development vs production, modify server.js:

const isDevelopment = process.env.NODE_ENV === 'development';

const csp = isDevelopment
  ? "default-src 'self' http://localhost:3000; script-src 'self' 'unsafe-inline' 'unsafe-eval'; ..."
  : "default-src 'self'; script-src 'self' 'unsafe-inline'; ...";

res.setHeader('Content-Security-Policy', csp);

Testing

Verify Headers in Development

# Start your dev server
npm run dev

# In another terminal, check headers
curl -I http://localhost:5173

Verify Headers in Production

# Build your app
npm run build

# Start production server
npm start

# Check headers
curl -I http://localhost:8080

Expected Headers

You should see all security headers in the response:

HTTP/1.1 200 OK
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; ...
X-Content-Type-Options: nosniff
Referrer-Policy: no-referrer
X-DNS-Prefetch-Control: off
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 0

Deployment

Vite-Shield generates production-ready configurations for various deployment platforms:

Node.js Hosting (Express Server)

  1. Build your application:

    npm run build
  2. Start the production server:

    npm start
  3. Or use PM2 for process management:

    pm2 start server.js --name my-app

Nginx

  1. Copy nginx.conf to your server
  2. Update paths and server_name as needed
  3. Reload Nginx:
    sudo nginx -t
    sudo nginx -s reload

Azure App Service

See DEPLOYMENT.md for detailed Azure deployment instructions.

Other Platforms

  • Vercel: Use the generated server.js as a serverless function
  • Netlify: Configure headers in netlify.toml (use nginx.conf as reference)
  • Docker: Use server.js in your Dockerfile
  • AWS Elastic Beanstalk: Use nginx.conf or server.js

For detailed deployment instructions, see DEPLOYMENT.md.

Troubleshooting

CSP Violations

If you see CSP violations in the browser console:

  1. Check the violation: The console will show which resource was blocked
  2. Update CSP: Modify the CSP in server.js or vite.config.ts
  3. Common fixes:
    • Add domain to connect-src for API calls
    • Add domain to img-src for external images
    • Add 'unsafe-inline' to style-src if needed (less secure)

Headers Not Appearing

  1. Check server is running: Ensure your server is actually running
  2. Check middleware order: Security headers middleware should be before routes
  3. Check browser cache: Clear cache or use incognito mode
  4. Verify configuration: Check that headers are set in the correct file

Server Won't Start

  1. Check Node.js version: Requires Node.js 14+ for ES modules
  2. Check dependencies: Ensure express is installed
  3. Check file paths: Verify dist/ directory exists after build
  4. Check port: Ensure port 8080 (or your PORT env var) is available

Content Security Policy (CSP) Guide

Understanding CSP Directives

| Directive | Controls | Example | |-----------|----------|---------| | default-src | Fallback for other directives | 'self' | | script-src | JavaScript sources | 'self' 'unsafe-inline' | | style-src | CSS sources | 'self' 'unsafe-inline' https://fonts.googleapis.com | | img-src | Image sources | 'self' data: blob: https://*.example.com | | font-src | Font sources | 'self' data: https://fonts.gstatic.com | | connect-src | API/fetch/WebSocket | 'self' https://api.example.com wss://ws.example.com | | frame-src | iframe sources | 'self' blob: | | media-src | Video/audio sources | 'self' blob: https://*.example.com | | frame-ancestors | Who can embed your page | 'self' |

Common CSP Patterns

React/Vue Applications:

script-src 'self' 'unsafe-inline'
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com

File Upload/Preview Applications:

img-src 'self' data: blob: https://*.blob.core.windows.net
frame-src 'self' blob:
media-src 'self' blob: https://*.blob.core.windows.net

API-Heavy Applications:

connect-src 'self' https://api.example.com https://*.blob.core.windows.net wss://ws.example.com

Best Practices

  1. Start Restrictive: Begin with a restrictive CSP and relax incrementally
  2. Test Thoroughly: Test in staging before production
  3. Monitor Violations: Use browser console to identify CSP violations
  4. Document Changes: Keep track of why each domain is allowed
  5. Regular Updates: Review and update CSP as your app evolves
  6. Use Nonces: Consider using nonces instead of 'unsafe-inline' for better security

Security Headers Explained

Strict-Transport-Security (HSTS)

Forces browsers to use HTTPS only. Once set, browsers will remember to use HTTPS for the specified duration.

Value: max-age=31536000; includeSubDomains; preload

  • max-age: Duration in seconds (1 year)
  • includeSubDomains: Applies to all subdomains
  • preload: Allows inclusion in browser HSTS preload lists

X-Frame-Options

Prevents clickjacking by controlling iframe embedding.

Value: SAMEORIGIN

  • Allows framing only from the same origin
  • Alternative: DENY (never allow framing)

Content-Security-Policy

Controls which resources can be loaded and executed, preventing XSS attacks.

Default Policy: Restrictive policy allowing only same-origin resources with necessary exceptions for common web app needs.

X-Content-Type-Options

Prevents MIME-type sniffing attacks.

Value: nosniff

  • Forces browsers to respect declared content types

Referrer-Policy

Controls how much referrer information is sent with requests.

Value: no-referrer

  • Never sends referrer information
  • Alternative: strict-origin-when-cross-origin for more permissive policy

Examples

Basic React App

# Create new Vite React app
npm create vite@latest my-app -- --template react
cd my-app

# Install dependencies
npm install

# Run vite-shield
npx vite-shield

# Start dev server (headers already configured)
npm run dev

Vue App

# Create new Vite Vue app
npm create vite@latest my-app -- --template vue
cd my-app

# Install dependencies
npm install

# Run vite-shield
npx vite-shield

# Build and serve
npm run build
npm start

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details.

Support

  • Issues: GitHub Issues
  • Documentation: See DEPLOYMENT.md for deployment guides
  • Security Headers Guide: Comprehensive guide included in deployment documentation

Related Projects


Made with ❤️ for secure web applications