Project setup and structure

Starting out with an organized development workflow

Development environment

Language version management tools like nvm are essential when working across multiple projects with different version requirements. I use npm because it’s the default package manager that comes with Node.js, though other package managers work equally well. Corepack ensures access to the appropriate package manager for each codebase regardless of personal preference. Although npm will not include Corepack by default, it will remain available as a separate installation for cross-project package manager compatibility.

Editor setup improves developer efficiency. Prioritize linter integration for code quality, LSP for type checking and autocomplete, and formatters for consistency. While automatic formatting helps maintain consistency, manual formatting control often produces cleaner results.

Top

Dependency management

Lock dependencies to prevent unexpected version changes that can break builds or introduce inconsistencies between team members. For web applications or sites, I categorize dependencies as production (necessary for building the website) versus development (linters, compilers, and development tools). Development dependencies can accept more frequent updates in version range specifiers since they don’t affect the final build output.

Regular dependency updates should be routine rather than intimidating when combined with strict code quality enforcement and automated testing that catch regressions early. You must balance version range stability with security updates, especially for development tools that change rapidly.

Cross-platform compatibility awareness helps avoid deployment surprises, particularly between Unix-like development environments and different production platforms.

Top

Framework migration

Capability Parcel Astro
SSG support Custom plugins required Built-in, first-class
TypeScript Supported Native integration
Component model None (HTML only) .astro components
Dev server Basic HMR Vite-powered HMR
Primary focus Application bundling Content-focused sites

The project began as a Parcel-based static site that required custom plugins to achieve static site generation capabilities. Astro treats static sites as first-class rather than an afterthought, eliminating the need for custom plugin development while providing built-in SSG optimizations and better performance.

Starting with Astro’s blog template and a strict TypeScript configuration, which included settings for build processes and development server setup, sped up development.

Top

Build process configuration

Build and deploy scripts (package.json)
"build": "astro build",
"postbuild": "./scripts/set-csp-header.ts", // Export SRI hashes to JSON
"predeploy": "npm run build",
"deploy": "terraform apply"

I prioritized security then performance because they are vital requirements for modern web projects. @kindspells/astro-shield provides essential security headers with SRI hashes, while @vite-pwa/astro delivers performance benefits through resource precaching that benefit even static sites.

@playform/compress handles asset optimization but relies on outdated tools like csso (conflicts with modern CSS) and html-minifier-terser (unmaintained). Manual optimization documented in optimizing-svgs.md addresses limitations with CSS background-image compression.

Strict configurations were carefully researched to incorporate established best practices and recently maintained plugins. The research process involved examining multiple configuration examples, plugin documentation, and community discussions to understand the implications of different rule sets. I resolved configuration conflicts between tools to keep both code quality and development efficiency. Some plugins required custom configuration due to project-specific requirements or compatibility issues with other tools in the development stack.

Top

Infrastructure organization

Terraform module organization
infrastructure/
├── amplify/          # App, branch, domain, headers
│   ├── main.tf
│   ├── dns.tf
│   └── variables.tf
├── remote-config/    # Terraform state backend
├── s3-bucket/        # Reusable S3 module
└── budget.tf         # Cost monitoring
main.tf               # Single entry point

The Terraform configuration consists of modular components handling different AWS infrastructure aspects. The Amplify module includes resources for the app, branch configuration, domain association, and custom headers. Additional modules manage S3 buckets, DNS configuration, and remote state storage.

Directory organization eliminated project root clutter that made it difficult to locate important files among numerous configuration files. Terraform modules organize components into well-known locations for easier navigation during maintenance and updates.

Top

Setup challenges

I researched environment variable management to determine appropriate patterns for both Terraform and Astro configurations. The .auto.tfvars.example pattern provides template guidance while maintaining security by excluding actual values from version control. Terraform automatically includes .auto.tfvars file when running commands, making this a convenient pattern for local configuration.

PWA integration presented compatibility challenges as Astro moves away from env.d.ts while @vite-pwa/astro still requires it. Resolving this required consulting documentation from both projects to ensure long-term compatibility and support.

The docs directory follows GitHub Pages patterns, providing a convenient location for documentation that doesn’t clutter the project root.

Top

Future improvements

Development environment management could benefit from better tools like devenv.sh, though such changes require considering workflow changes versus benefits. Similarly, automated formatting through lint-staged could reduce manual formatting effort while maintaining code consistency.

The current build optimization stack has maintenance challenges with outdated dependencies like csso and html-minifier-terser. Finding modern replacements that handle CSS background-image optimization and reliable HTML minification would eliminate these technical debt concerns. html-minifier-next is a likely candidate for HTML minification options, and I will consider adding support to @playform/compress.

Direct Vite integration for CSS processing through lightningcss could simplify the build pipeline and provide better CSS optimization. Ongoing plugin evaluation ensures the project benefits from community improvements while avoiding abandoned or problematic dependencies.

Top