Scalable directory structure for managing CSS, JavaScript, images, and third-party dependencies with support for theme-specific and shared resources

Static Assets Organisation

Introduction

The MintyFlask static assets organisation provides a scalable, maintainable structure for managing CSS, JavaScript, images, and third-party dependencies. This system separates concerns logically - distinguishing between foundational styles, reusable components, and third-party integrations - making it intuitive to locate files and predict where new code should be placed.

The structure supports both theme-specific assets and shared resources used across multiple themes. Developers have flexibility in dependency management: use CDNs for quick prototyping, or self-host in the shared vendor directory for production control and reliability.

Key architectural principles:

  • Clear separation between custom code and vendor libraries
  • Predictable file locations following established conventions
  • Flexible dependency management supporting CDN or self-hosted approaches
  • Logical import cascade from foundations through components to integrations

This organisation reduces cognitive load, speeds up onboarding, and makes large codebases manageable as projects grow.


Directory Structure Overview

Theme-Specific Assets

./static/
├── css/                    # All stylesheets
│   ├── components/         # Reusable component styles
│   ├── foundations/        # Base system (typography, colours, spacing)
│   ├── integrations/       # Third-party CSS customisations
│   ├── theme/              # Theme-specific variables
│   └── utilities/          # Utility classes
├── js/                     # All JavaScript
│   ├── components/         # Reusable UI components
│   └── integrations/       # Third-party JS integrations
├── images/                 # Static images and icons
└── vendor/                 # Theme-specific third-party libraries (unmodified)

Shared Assets (Project-Wide)

/shared/
├── vendor/                 # Common third-party libraries used across themes
│   └── photoswipe/         # Example: PhotoSwipe library files
├── fonts/                  # Shared web fonts
├── icons/                  # Shared icon sets
└── macros/                 # Reusable template macros

File Placement Guidelines

CSS Organisation

  • css/foundations/ - Core design system files (typography, colours, spacing, layout)
  • css/components/ - Self-contained component styles (buttons, cards, photos, navigation)
  • css/integrations/ - Customisations for third-party libraries (PhotoSwipe, Leaflet, etc.)
  • css/theme/ - Theme-specific variables and overrides
  • css/utilities/ - Single-purpose utility classes
  • css/input.css - Main CSS entry point with imports

JavaScript Organisation

  • js/components/ - Reusable UI components (photo galleries, modals, forms)
  • js/integrations/ - Third-party library setup and configuration
  • js/dashboard.js - Page-specific scripts (when needed)

Assets & Vendor

  • images/ - Static images, icons, favicons
  • vendor/ - Theme-specific third-party libraries (unmodified)
  • /shared/vendor/ - Project-wide third-party libraries used across multiple themes

Usage Examples

Adding a New Component

# CSS component
touch static/css/components/modal.css

# JavaScript component
touch static/js/components/modal.js

# Update input.css to include the new CSS component

Adding a Third-Party Integration

# Download vendor files
curl -o static/vendor/leaflet/leaflet.js [URL]
curl -o static/vendor/leaflet/leaflet.css [URL]

# Create integration files
touch static/css/integrations/leaflet.css    # Custom styling
touch static/js/integrations/leaflet.js      # Setup & configuration

Adding a Shared Third-Party Integration

# For libraries used across multiple themes (e.g., PhotoSwipe)
mkdir -p shared/vendor/photoswipe
curl -o shared/vendor/photoswipe/photoswipe.esm.js [URL]
curl -o shared/vendor/photoswipe/photoswipe.css [URL]

# Create theme-specific integration files
touch static/css/integrations/photoswipe.css    # Custom styling
touch static/js/integrations/photoswipe.js      # Setup & configuration

Template Integration

<!-- Base template includes main CSS -->
<link rel="stylesheet" href="{{ theme_static('css/output.css') }}">

<!-- Page-specific integration -->
<script type="module" src="{{ theme_static('js/integrations/photoswipe.js') }}">

Best Practices

  1. Keep vendor files unmodified - Use integration files for customisations
  2. Use semantic naming - photo-gallery.js not alpine-photo-components.js
  3. Follow the cascade - foundations → components → integrations → page-specific
  4. Document dependencies - Note which vendor files each integration requires
  5. Version control vendor files - Include in repository for build reproducibility
  6. Choose vendor location strategically - Use /shared/vendor/ for common dependencies across themes; use ./static/vendor/ for theme-specific libraries

Next Steps

Now that you understand the static assets organisation, explore these related topics:

  • CSS Architecture - Understand the five-layer CSS cascade system and how it integrates with the asset structure
  • Component Development - Learn how to create reusable components following established patterns
  • Template Resolution - Understand how templates and static assets work together in the three-layer system
  • Mixins - Explore extending functionality with theme mixins
  • Theme Creation - Build custom themes using the established asset organisation