Your Next.js App Is Probably Breaking Indian Law
India's Digital Personal Data Protection Act (DPDP), 2023 is now in effect. If your app serves Indian users and does any of the following, you're non-compliant:
- Loads Google Analytics / Facebook Pixel / Hotjar before the user consents
- Stores Aadhaar numbers, PAN, phone numbers in
localStoragewithout encryption - Sets
document.cookiewithout a consent check - Sends PII (email, phone) to analytics platforms
- Has no privacy policy page
- Exports user data in bulk without audit logging
Most Indian dev teams don't even know this. The fines go up to ₹250 crore.
Introducing @dpdp-india/audit
A static analysis CLI that scans your JS/TS codebase and flags DPDP violations — like ESLint, but for privacy.
npx @dpdp-india/audit ./src
Output looks like this:
DPDP Audit Report
Framework: Next.js | Files scanned: 47
src/components/Analytics.tsx
✗ 12:5 Google Analytics loaded without consent guard dpdp/no-unguarded-tracker
→ Wrap in a consent check: if (hasConsent('analytics')) { ... }
src/lib/cache.ts
✗ 8:3 PII stored in localStorage without encryption dpdp/no-raw-pii-storage
→ Use encrypted storage or a server-side session
src/utils/tracking.ts
✗ 23:7 PII field 'email' passed to analytics call dpdp/no-pii-in-analytics
→ Remove PII fields or hash before sending
3 errors, 0 warnings
13 Rules, Real Violations
Not theoretical. These catch patterns I've seen in production Indian apps:
| Rule | What it catches |
|---|---|
no-unguarded-tracker |
GA/GTM/FB/Hotjar/Clarity loaded without consent |
no-raw-pii-storage |
Aadhaar, PAN, email, phone in localStorage/sessionStorage |
no-unconsented-cookies |
document.cookie writes without consent check |
no-third-party-scripts |
Tracker <script> tags in HTML files |
no-pii-in-analytics |
PII fields sent to tracking calls |
no-pii-in-headers |
PII leaked in HTTP headers |
no-unguarded-plausible |
PlausibleProvider without consent wrapper |
no-unencrypted-pii-cache |
PII in cache/Redis without encryption |
no-unguarded-database-export |
DB exports without access control |
no-bulk-export-without-audit |
Bulk data export without audit trail |
no-impersonation-without-audit |
User impersonation without logging |
require-data-deletion |
No hard-delete endpoint (only soft-delete) |
require-privacy-policy |
Missing privacy policy page/route |
Next.js? Drop-in Consent SDK
The scanner is one half. The other half is a ready-to-use consent system for Next.js apps:
npm install @dpdp-india/audit
1. Add ConsentProvider + Banner
// app/layout.tsx
import { ConsentProvider, ConsentBanner } from '@dpdp-india/audit/next'
export default function RootLayout({ children }) {
return (
<html>
<body>
<ConsentProvider>
{children}
<ConsentBanner
privacyPolicyUrl="/privacy-policy"
companyName="Your Company"
/>
</ConsentProvider>
</body>
</html>
)
}
You get a styled banner with Accept All / Reject / Preferences — handles 4 categories: necessary, analytics, marketing, preferences. State persists in dpdp_consent cookie.
2. Guard Your Scripts
Replace next/script with DpdpScript. Only loads after consent:
import { DpdpScript } from '@dpdp-india/audit/next'
<DpdpScript
consentCategory="analytics"
src="https://www.googletagmanager.com/gtag/js?id=G-XXXXX"
strategy="afterInteractive"
/>
3. Use the Hook Anywhere
import { useConsent } from '@dpdp-india/audit/next'
function MyComponent() {
const { hasConsent, acceptAll, rejectAll } = useConsent()
if (hasConsent('analytics')) {
// safe to fire analytics
}
}
4. Build-time Enforcement
Add to next.config.js — fails the build if violations exist:
import { withDpdpAudit } from '@dpdp-india/audit/next'
export default withDpdpAudit(nextConfig, {
failOnError: true,
ignore: ['node_modules/**', '.next/**'],
})
CI/CD Integration
SARIF output plugs into GitHub Code Scanning:
# .github/workflows/dpdp.yml
name: DPDP Compliance
on: [push, pull_request]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npx @dpdp-india/audit ./src --format sarif --output dpdp.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: dpdp.sarif
Violations show up as annotations on your PRs.
How It Works Under the Hood
The scanner uses ts-morph for AST analysis and htmlparser2 for HTML files. Each rule is a function that receives parsed source files and returns violations with:
- File path, line, column
- Severity (error/warning)
- Human-readable message
- Fix suggestion
No runtime overhead. Static analysis only. Auto-detects your framework (Next.js, React, Angular, Vue, Svelte) and adjusts rules accordingly.
Programmatic API
Use it in your own tools:
import { scan } from '@dpdp-india/audit'
const result = await scan('./src', {
rules: ['no-unguarded-tracker', 'no-raw-pii-storage'],
ignore: ['tests/**'],
})
console.log(`${result.violations.length} violations found`)
Why I Built This
Every Indian startup I've audited has at least 3-4 DPDP violations. Most don't know the act exists. The penalty structure is severe — up to ₹250 crore per instance.
There's no ESLint plugin for this. No Semgrep rules. Nothing in the JS/TS ecosystem that understands Indian privacy law.
So I built one.
Get Started
# Scan your project right now
npx @dpdp-india/audit ./src
GitHub: github.com/babbarankit/dpdp-audit
npm: @dpdp-india/audit
Star the repo if this is useful. PRs welcome — especially for new rules and framework integrations.
Top comments (0)