Skip to content

erichchampion/defroster

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

60 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Defroster

An anonymous, open-source community safety platform for real-time ICE, Army, and Police sighting alerts.

Defroster is a Progressive Web App (PWA) that empowers communities to stay informed and connected through anonymous, location-based safety alerts. Users can report sightings with a single tap, and nearby community members receive instant notificationsβ€”all while maintaining complete privacy and anonymity.


🌟 About This Project

Defroster was created in response to the October 2, 2024 federal raid on a South Shore Drive apartment building in Chicago, where families were forcibly removed from their homes during a multi-agency operation involving Border Patrol, the FBI, and the ATF.

This is open-source software. We encourage anyone to use, modify, and adapt this codebase to create similar platforms tailored to their own community's needs. Whether you're organizing mutual aid networks, neighborhood watch programs, or other community safety initiatives, this platform provides the foundation you need.


✨ Key Features

Privacy & Anonymity

  • πŸ”’ No personal data stored - ever
  • πŸ“ Location randomization to nearest city block (~250 feet / ~76 meters)
  • πŸ” Anonymous device IDs using UUID v4
  • πŸ—‘οΈ Auto-deletion: Reports removed from server after 1 day, from device after 1 week
  • 🚫 No user accounts or authentication required

Real-Time Alerts

  • πŸ“± Push notifications for sightings within 5 miles
  • πŸ—ΊοΈ Interactive map with age-based opacity (older reports fade)
  • πŸ“Š List view of nearby sightings with timestamps
  • ⚑ Instant reporting - one tap to alert your community

Technology

  • 🌐 Progressive Web App (PWA) - installable on any device
  • 🌍 Multilingual - English & Spanish with automatic browser detection
  • πŸ“΄ Offline-capable with IndexedDB caching
  • πŸ”„ Real-time synchronization via Firebase Cloud Messaging
  • 🎨 Modern UI with Tailwind CSS and responsive design

Developer-Friendly

  • πŸ—οΈ Modular architecture with abstraction layers
  • πŸ”Œ Easy provider switching (Firebase β†’ MongoDB, PostgreSQL, etc.)
  • πŸ§ͺ Comprehensive test coverage (93 tests passing)
  • πŸ“ TypeScript for type safety
  • 🎯 Clean code with ESLint and best practices

πŸš€ Quick Start

Prerequisites

  • Node.js 20+ and npm
  • A Firebase account (free tier works)
  • Basic knowledge of Next.js and React

1. Clone and Install

git clone https://github.com/erichchampion/defroster.git
cd defroster
npm install

2. Firebase Project Setup

  1. Create a new Firebase project at Firebase Console
  2. Enable Firestore Database:
    • Go to Project Settings β†’ Build β†’ Firestore Database β†’ Create Database
    • Start in production mode
  3. Enable Cloud Messaging:
    • Go to Project Settings β†’ Cloud Messaging
    • Enable Cloud Messaging API
  4. Generate Web Push Certificate:
    • In Cloud Messaging settings, scroll to "Web Push certificates"
    • Click "Generate key pair"
    • Save the VAPID key
  5. Get Web App Configuration:
    • Go to Project Settings β†’ General
    • Under "Your apps", click "Web" (</> icon)
    • Register your app and copy the config

3. Environment Configuration

Create .env.local from the example:

cp .env.local.example .env.local

Edit .env.local with your Firebase credentials:

# Firebase Web Configuration
NEXT_PUBLIC_FIREBASE_API_KEY=AIza...
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your-project.appspot.com
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=123456789
NEXT_PUBLIC_FIREBASE_APP_ID=1:123456789:web:abc123
NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=G-ABC123
NEXT_PUBLIC_FIREBASE_VAPID_KEY=BN4bX... (from step 4 above)

# Base URL for origin validation (REQUIRED)
NEXT_PUBLIC_BASE_URL=http://localhost:3000

# Generate secure CRON secret (run: openssl rand -hex 32)
CRON_SECRET=your_64_character_hex_key

# Upstash Redis for distributed rate limiting (optional for development, required for production)
# UPSTASH_REDIS_REST_URL=https://...upstash.io
# UPSTASH_REDIS_REST_TOKEN=...

# For production (optional for development)
FIREBASE_SERVICE_ACCOUNT_KEY={"type":"service_account",...}

4. Upstash Redis Setup (Required for Production)

For distributed rate limiting across serverless instances:

  1. Go to Upstash Console
  2. Create a new Redis database (free tier available)
  3. Click on your database to view details
  4. Copy the REST API credentials:
    • UPSTASH_REDIS_REST_URL
    • UPSTASH_REDIS_REST_TOKEN
  5. Add these to your .env.local file

Why Upstash Redis is required:

  • In-memory rate limiting doesn't work in serverless (Vercel, AWS Lambda)
  • Each serverless instance would have separate counters
  • Attackers could bypass rate limits by hitting different instances
  • Upstash Redis provides shared state across all instances

Development note: The app will run without Upstash Redis (rate limiting disabled), but you'll see warnings. This is acceptable for local development.

Pricing: Upstash offers a generous free tier with 10,000 commands per day.

5. Firebase Admin SDK (Optional for Development)

For local development, the app will work without the Admin SDK for notifications. For full functionality:

  1. Go to Firebase Console β†’ Project Settings β†’ Service Accounts
  2. Click "Generate new private key"
  3. Download the JSON file
  4. Copy the entire JSON content and add to .env.local:
FIREBASE_SERVICE_ACCOUNT_KEY='{"type":"service_account","project_id":"your-project",...}'

Note: For development, you can skip this and notifications will be simulated client-side.

6. Firestore Security Rules

Deploy the security rules:

# Install Firebase CLI if you haven't
npm install -g firebase-tools

# Login to Firebase
firebase login

# Initialize Firebase (select existing project)
firebase init firestore

# Deploy security rules
firebase deploy --only firestore:rules

The firestore.rules file is already configured with secure rules:

  • βœ… Messages: Public read, server-write only
  • βœ… Devices: No client access (Admin SDK only)

7. Firestore Indexes

Firestore will prompt you to create indexes when you first query. Alternatively, create them manually:

  1. Go to Firestore Console β†’ Indexes
  2. Create composite index for messages:
    • Collection ID: messages
    • Fields: geohash (Ascending), expiresAt (Ascending)
  3. Create composite index for devices:
    • Collection ID: devices
    • Fields: geohash (Ascending), updatedAt (Ascending)

8. Run Development Server

npm run dev

Open http://localhost:3000 and grant location permissions.


πŸ—οΈ Production Deployment

Option 1: Vercel (Recommended)

  1. Push to GitHub:

    git add .
    git commit -m "Initial Defroster setup"
    git push origin main
  2. Deploy to Vercel:

    • Go to vercel.com and sign in with GitHub
    • Click "New Project" and import your repository
    • Add all environment variables from .env.local
    • Click "Deploy"
  3. Configure Custom Domain (Optional):

    • In Vercel project settings β†’ Domains
    • Add your custom domain
    • Update ALLOWED_ORIGIN in environment variables
  4. Set Up Automated Cleanup (Optional but recommended): (Now configured through the vercel.json file)

    • In Vercel project β†’ Settings β†’ Cron Jobs
    • Create a new cron job:
      • Path: /api/cleanup-messages
      • Schedule: 0 * * * * (hourly)
      • Add custom header: x-cron-secret: your_cron_secret

Make sure to add NEXT_PUBLIC_BASE_URL to your Vercel environment variables with the actual deployment URL (e.g., https://your-app.vercel.app).

Option 2: Firebase Hosting + Cloud Functions

  1. Build the app:

    npm run build
  2. Deploy Cloud Functions (for cleanup):

    cd functions
    npm install
    cd ..
    firebase deploy --only functions
  3. Deploy hosting:

    firebase deploy --only hosting

Option 3: Self-Hosted (VPS/Docker)

  1. Build:

    npm run build
  2. Run production server:

    npm start
  3. Use PM2 for process management:

    npm install -g pm2
    pm2 start npm --name "defroster" -- start
    pm2 save
    pm2 startup
  4. Configure Nginx reverse proxy:

    server {
        listen 80;
        server_name yourdomain.com;
    
        location / {
            proxy_pass http://localhost:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }
  5. Get SSL certificate:

    sudo certbot --nginx -d yourdomain.com

πŸ§ͺ Testing

Run the full test suite:

npm test

Run tests in watch mode:

npm run test:watch

Generate coverage report:

npm run test:coverage

All 128 tests cover:

  • Component rendering and interactions
  • API routes and error handling
  • Service integrations (Firebase, IndexedDB)
  • Hooks and state management
  • Geolocation and messaging

Generate API Documentation

Generate TypeDoc API documentation:

npm run docs

This generates comprehensive API documentation from TypeScript/JSDoc comments into docs/api/. The documentation covers all abstractions, services, contexts, hooks, and utilities.

View the generated documentation by opening docs/api/index.html in your browser.


🌐 Internationalization (i18n)

Defroster supports multiple languages with SEO-friendly, server-side rendered locale routes:

URL Structure

  • / β†’ Redirects to /en-us (default) or /es-us (Spanish browsers)
  • /en-us β†’ English version (server-rendered, crawlable)
  • /es-us β†’ Spanish version (server-rendered, crawlable)

Current Languages

  • πŸ‡ΊπŸ‡Έ English (default) - /en-us
  • πŸ‡ͺπŸ‡Έ Spanish (espaΓ±ol) - /es-us

How It Works

Middleware (middleware.ts) detects browser language from the Accept-Language header and redirects to the appropriate locale. Each locale has:

  • βœ… Server-side rendered metadata (title, description, Open Graph, Twitter cards)
  • βœ… Proper <html lang="en"> or <html lang="es"> attributes
  • βœ… Localized content from lib/i18n/en.json or lib/i18n/es.json
  • βœ… SEO-friendly URLs for better search engine indexing

Example:

# English browser β†’ redirects to /en-us
curl -H "Accept-Language: en-US" https://defroster.us/

# Spanish browser β†’ redirects to /es-us
curl -H "Accept-Language: es-MX" https://defroster.us/

Adding New Languages

  1. Update i18n utilities (lib/i18n/i18n.ts):
export type Locale = 'en-us' | 'es-us' | 'fr-us';  // Add new locale
export const locales: Locale[] = ['en-us', 'es-us', 'fr-us'];
  1. Create translation file (lib/i18n/fr.json):
{
  "app": {
    "name": "Defroster",
    "title": "Defroster - Signaler les Observations"
  }
  // ... copy structure from en.json and translate
}
  1. Update middleware (middleware.ts):
function getLocale(request: NextRequest): string {
  const acceptLanguage = request.headers.get('accept-language');
  // ... existing code ...

  for (const lang of languages) {
    if (lang.code.startsWith('es')) return 'es-us';
    if (lang.code.startsWith('fr')) return 'fr-us';  // Add detection
  }

  return 'en-us';
}
  1. Build and test:
npm run build
npm start
curl -H "Accept-Language: fr-FR" http://localhost:3000/

πŸ“± Installing as PWA

iOS (Safari)

  1. Open the app in Safari
  2. Tap the Share button (square with arrow)
  3. Scroll and tap "Add to Home Screen"
  4. Tap "Add"

Android (Chrome)

  1. Open the app in Chrome
  2. Tap the menu (three dots)
  3. Tap "Install app" or "Add to Home Screen"

Desktop (Chrome/Edge)

  1. Look for the install icon (βŠ•) in the address bar
  2. Click to install
  3. App opens in its own window

πŸ›οΈ Architecture

Tech Stack

  • Frontend: Next.js 15, React 19, TypeScript, Tailwind CSS
  • Backend: Next.js API Routes (serverless)
  • Database: Firebase Firestore with geohash indexing
  • Messaging: Firebase Cloud Messaging (FCM)
  • Maps: Leaflet with OpenStreetMap
  • Caching: IndexedDB (Dexie.js abstraction)
  • Geospatial: geofire-common for efficient radius queries

Key Design Decisions

1. Privacy by Design

  • No sender location tracking: Only sighting location is stored
  • Geohash precision: 7 characters (~76m) balances utility and privacy
  • Device IDs: UUID v4 instead of FCM tokens for anonymity
  • No authentication: Reduces data collection and barriers to use

2. Abstraction Layers

The codebase uses interfaces to allow easy provider switching:

IMessagingService (lib/abstractions/messaging-service.ts)

  • Current: Firebase Cloud Messaging
  • Swap with: OneSignal, Pusher, custom WebSocket, etc.

IDataService (lib/abstractions/data-service.ts)

  • Current: Firebase Firestore
  • Swap with: MongoDB, PostgreSQL+PostGIS, Supabase, etc.

IStorageService (lib/abstractions/storage-service.ts)

  • Current: IndexedDB
  • Swap with: LocalStorage, AsyncStorage, etc.

3. Client-First Architecture

  • Messages cached locally in IndexedDB
  • Works offline with cached data
  • Optimistic UI updates
  • Background sync when connection returns

Project Structure

defroster/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ [locale]/               # Localized routes (SSR)
β”‚   β”‚   β”œβ”€β”€ layout.tsx          # Locale-specific layout with i18n metadata
β”‚   β”‚   └── page.tsx            # Main app page (client component)
β”‚   β”œβ”€β”€ api/                    # API routes (serverless functions)
β”‚   β”‚   β”œβ”€β”€ cleanup-messages/   # Cron job for message cleanup
β”‚   β”‚   β”œβ”€β”€ get-messages/       # Fetch nearby messages
β”‚   β”‚   β”œβ”€β”€ register-device/    # Register for notifications
β”‚   β”‚   └── send-message/       # Create new sighting report
β”‚   β”œβ”€β”€ components/             # React components
β”‚   β”‚   β”œβ”€β”€ LocationPermission.tsx
β”‚   β”‚   β”œβ”€β”€ MessageForm.tsx
β”‚   β”‚   β”œβ”€β”€ MessageList.tsx
β”‚   β”‚   └── SightingMap.tsx
β”‚   β”œβ”€β”€ hooks/                  # Custom React hooks
β”‚   β”‚   β”œβ”€β”€ useGeolocation.ts
β”‚   β”‚   └── useMessaging.ts
β”‚   β”œβ”€β”€ ClientProviders.tsx     # Client-side context providers
β”‚   β”œβ”€β”€ layout.tsx              # Root layout (minimal)
β”‚   └── globals.css             # Global styles
β”œβ”€β”€ middleware.ts               # Locale detection & redirection
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ abstractions/           # Service interfaces
β”‚   β”‚   β”œβ”€β”€ data-service.ts
β”‚   β”‚   β”œβ”€β”€ messaging-service.ts
β”‚   β”‚   └── storage-service.ts
β”‚   β”œβ”€β”€ constants/              # App constants
β”‚   β”‚   β”œβ”€β”€ app.ts
β”‚   β”‚   └── colors.ts
β”‚   β”œβ”€β”€ contexts/               # React contexts
β”‚   β”‚   β”œβ”€β”€ I18nContext.tsx
β”‚   β”‚   └── ServicesContext.tsx
β”‚   β”œβ”€β”€ firebase/               # Firebase configuration
β”‚   β”‚   β”œβ”€β”€ admin.ts
β”‚   β”‚   └── config.ts
β”‚   β”œβ”€β”€ i18n/                   # Internationalization
β”‚   β”‚   β”œβ”€β”€ en.json
β”‚   β”‚   β”œβ”€β”€ es.json
β”‚   β”‚   └── i18n.ts
β”‚   β”œβ”€β”€ services/               # Service implementations
β”‚   β”‚   β”œβ”€β”€ fcm-messaging-service.ts
β”‚   β”‚   β”œβ”€β”€ firestore-data-service.ts
β”‚   β”‚   └── indexeddb-storage-service.ts
β”‚   β”œβ”€β”€ types/                  # TypeScript types
β”‚   β”‚   └── message.ts
β”‚   └── utils/                  # Utility functions
β”‚       β”œβ”€β”€ geohash.ts
β”‚       β”œβ”€β”€ register-sw.ts
β”‚       β”œβ”€β”€ time-formatter.ts
β”‚       └── time-formatter-i18n.ts
β”œβ”€β”€ public/
β”‚   β”œβ”€β”€ appicon/                # PWA icons (all sizes)
β”‚   β”œβ”€β”€ firebase-messaging-sw.js # Service worker
β”‚   └── manifest.json           # PWA manifest
β”œβ”€β”€ functions/                  # Firebase Cloud Functions
β”‚   └── src/
β”‚       └── cleanup.ts          # Scheduled cleanup function
β”œβ”€β”€ __tests__/                  # Jest tests
β”œβ”€β”€ firestore.rules             # Firestore security rules
β”œβ”€β”€ firebase.json               # Firebase configuration
└── package.json

πŸ”’ Security & Privacy

Current Security Features

βœ… Firestore Security Rules: Server-write only for messages and devices βœ… Origin Validation (BFF Pattern): API routes validate request origin using NEXT_PUBLIC_BASE_URL βœ… CORS Protection: Strict origin enforcement βœ… Input Validation: All user inputs validated with type checking and range limits βœ… Distributed Rate Limiting: Upstash Redis-based rate limiting (5/min sends, 3/min registrations, 20/min reads) βœ… Timing Attack Protection: Constant-time comparison for CRON secrets βœ… Security Headers: CSP, X-Frame-Options, X-Content-Type-Options, HSTS βœ… No XSS Vulnerabilities: React sanitizes all inputs βœ… HTTPS Only: Enforced in production βœ… Environment Validation: Startup checks for required configuration

Security Architecture: BFF Pattern

This app uses the Backend-for-Frontend (BFF) pattern for security:

  • Client makes requests without exposed API keys
  • Next.js API Routes validate the request origin matches NEXT_PUBLIC_BASE_URL
  • Server-side secrets (CRON_SECRET, Firebase Admin SDK) never exposed to clients

This prevents the critical vulnerability where API keys are embedded in client JavaScript.

Important Production Considerations

1. Distributed Rate Limiting with Upstash Redis

βœ… Now implemented using Upstash Redis for serverless-friendly rate limiting:

  • Works across multiple serverless instances on Vercel
  • Persists between deployments
  • Shared state across all instances
  • Automatic cleanup via Redis TTL
  • Simple configuration with REST API

Setup required:

  1. Create account at Upstash Console
  2. Create a Redis database
  3. Copy REST API credentials to environment variables
  4. See Setup section above

How it works:

// Rate limiting uses Upstash Redis REST API
import { Redis } from '@upstash/redis';

const count = await redis.incr(`ratelimit:${clientId}`);
if (count === 1) {
  await redis.expire(key, windowSeconds);
}

Fallback behavior: If Upstash Redis is not configured, rate limiting is disabled (with warnings). This allows development without Redis, but production deployments should always configure Upstash Redis.

2. Environment Variables

  • Never commit .env.local to version control
  • Use secrets management (Vercel Environment Variables, AWS Secrets Manager, etc.)
  • Rotate CRON_SECRET regularly (recommended: quarterly)
  • Ensure NEXT_PUBLIC_BASE_URL matches your production domain exactly
  • Required for production: Configure Upstash Redis for distributed rate limiting

3. Monitoring & Alerting

Set up monitoring for:

  • Unusual spike in API requests (potential abuse)
  • 403 errors (origin validation failures)
  • 429 errors (rate limit hits)
  • Firestore quota usage
  • Failed notification deliveries

Recommended tools:

  • Error tracking: Sentry, LogRocket
  • Uptime monitoring: Better Uptime, UptimeRobot
  • Firestore alerts: Firebase Console β†’ Usage and billing

4. Firestore Security

  • Security rules are already configured (see firestore.rules)
  • Review rules regularly, especially if modifying data structure
  • Enable audit logging in Firebase Console
  • Set up billing alerts to prevent unexpected costs
  • Consider Firestore backup strategy for disaster recovery

πŸ”„ Switching Providers

Thanks to abstraction layers, you can easily swap providers without changing business logic.

Example: Switch to MongoDB

  1. Create MongoDB implementation:
// lib/services/mongodb-data-service.ts
import { IDataService } from '@/lib/abstractions/data-service';

export class MongoDBDataService implements IDataService {
  async saveMessage(message: Message): Promise<void> {
    // MongoDB implementation
  }

  async getNearbyMessages(location: GeoLocation, radius: number): Promise<Message[]> {
    // Use MongoDB geospatial queries
  }

  // ... implement all interface methods
}
  1. Update context:
// lib/contexts/ServicesContext.tsx
import { MongoDBDataService } from '@/lib/services/mongodb-data-service';

const dataService = new MongoDBDataService();

That's it! No changes needed in components or hooks.


🀝 Adapting for Your Community

This platform is designed to be easily customized for different use cases:

Suggested Modifications

  1. Change Sighting Types:

    • Edit lib/types/message.ts to change from ICE/Army/Police to your needs
    • Update lib/constants/colors.ts for custom colors and emojis
    • Modify lib/i18n/en.json and lib/i18n/es.json for new labels
  2. Adjust Radius:

    • Edit lib/constants/app.ts to change default radius
    • Update privacy notices in translation files
  3. Custom Branding:

    • Replace icons in public/appicon/
    • Update public/manifest.json with new name and description
    • Modify app/layout.tsx metadata
  4. Add Features:

    • Photos/videos of sightings
    • Severity levels
    • Custom tags or categories
    • Direct messaging
    • Community forums

Example Use Cases

  • πŸ₯ Healthcare Access: Report medication availability, clinic wait times
  • 🚨 Emergency Response: Community-organized disaster response
  • πŸŒ† Neighborhood Watch: Report suspicious activity
  • 🚧 Infrastructure Issues: Potholes, broken streetlights, flooding
  • πŸ›οΈ Civic Engagement: Protest locations, voter registration drives
  • 🍲 Mutual Aid: Food distribution, supply sharing

πŸ“Š Performance & Scalability

Current Performance

  • ⚑ Lighthouse Score: 95+ (Performance, Accessibility, Best Practices, SEO)
  • πŸ“¦ Bundle Size: ~188 kB First Load JS
  • πŸš€ Time to Interactive: < 2s on 4G
  • πŸ“± Mobile Optimized: Responsive design, touch-friendly

Scaling Considerations

Up to 10,000 users:

  • βœ… Firebase free tier sufficient
  • βœ… No changes needed

10,000 - 100,000 users:

  • πŸ’‘ Upgrade to Firebase Blaze plan
  • πŸ’‘ Add CDN (Vercel, Cloudflare)
  • πŸ’‘ Implement caching strategy

100,000+ users:

  • πŸ”§ Consider database sharding by region
  • πŸ”§ Move to dedicated infrastructure
  • πŸ”§ Implement advanced caching (Redis)
  • πŸ”§ Use load balancer

πŸ› Troubleshooting

"Permission denied" for location

  • iOS Safari: Settings β†’ Safari β†’ Location β†’ While Using the App
  • Android Chrome: Settings β†’ Site Settings β†’ Location β†’ Allow

Push notifications not working

  • βœ… Check VAPID key is correct in .env.local
  • βœ… Verify Firebase Cloud Messaging is enabled
  • βœ… Check browser supports notifications (not all do)
  • βœ… Ensure HTTPS in production (required for service workers)

Map not displaying

  • βœ… Check console for Leaflet errors
  • βœ… Verify location permissions granted
  • βœ… Check network tab for tile loading errors

Build errors

# Clear Next.js cache
rm -rf .next

# Clear node modules and reinstall
rm -rf node_modules package-lock.json
npm install

# Rebuild
npm run build

πŸ“„ License

MIT License - see LICENSE file for details.

You are free to:

  • βœ… Use this code for any purpose (commercial or non-commercial)
  • βœ… Modify and adapt it to your needs
  • βœ… Distribute copies
  • βœ… Sublicense

Under the condition that:

  • πŸ“ You include the original license and copyright notice

πŸ™ Acknowledgments


πŸ“ž Support & Contributing

Getting Help

  • πŸ“– Check this README first
  • πŸ› Search existing GitHub Issues
  • πŸ’¬ Open a new issue for bugs or feature requests

Contributing

We welcome contributions! Whether it's:

  • πŸ› Bug fixes
  • ✨ New features
  • πŸ“ Documentation improvements
  • 🌍 Translations
  • 🎨 UI/UX enhancements

To contribute:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

🌍 Make It Your Own

This is your platform now. Whether you're organizing community safety networks, mutual aid programs, or something entirely new - we're excited to see what you build.

Need help adapting Defroster for your community? Open an issue and we'll do our best to help.

Built something amazing with this code? Share it! We'd love to see how communities are using this platform.


Stay safe. Stay connected. Stay anonymous.

Defroster - Built by the community, for the community.

About

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors