
AssetStack: A Modern Approach to Static Asset Management
Manage your static assets like a professional, with type safety and team collaboration built-in.
Introduction
If you've worked on a modern JavaScript web project, especially with TypeScript, you know that managing static assets can become surprisingly complex. As projects scale, teams often struggle with:
- Inconsistent asset naming conventions
- Lack of type safety for image paths
- No central repository for design and engineering teams
- Sub-optimal image optimization pipelines
AssetStack aims to solve these problems with a two-pronged approach: a user-friendly web interface for designers and a CLI tool for developers, creating a seamless asset management workflow between teams.
System Architecture
AssetStack consists of two main components that work together to create a seamless experience:
- Web Interface - A user-friendly GUI designed primarily for design teams to upload, organize, and manage assets. This provides visual browsing, tagging, and version control for all project assets.
- CLI Tool - Connects to the web platform, allowing developers to pull TypeScript type definitions for the assets and use them with autocomplete in their projects. The CLI handles synchronization between the codebase and the asset repository.
Tech Stack: Embracing the "Boring" for Speed
For this project, I made a deliberate choice to optimize for development speed rather than exploring new technologies. This led me to the T3 stack, popularized by Theo (t3.gg), which includes:
- Next.js - For the web interface, providing both frontend and API routes
- Drizzle ORM - Type-safe database operations with minimal boilerplate
- MySQL - Reliable relational database for storing metadata and relationships
- Tailwind CSS with shadcn/ui - For rapid UI development with consistent design
This choice taught me a valuable lesson: sometimes using familiar, "boring" technology allows you to focus on solving the actual problem rather than fighting with new tools. For production-ready projects with real deadlines, this approach significantly improved my delivery time.
Core Features
Repository-Based Organization
AssetStack organizes assets using a repository model similar to GitHub:
- Each project gets its own repository of assets
- Granular access control for team members
- GitHub integration automatically syncs collaborators from connected repositories
- Version history for all assets, allowing rollbacks if needed
This model makes AssetStack particularly valuable for teams where designers and developers need to collaborate on asset management without stepping on each other's toes.
Upload Pipeline: Optimized for Performance
The upload system was built with web performance as a priority:
- Chunked uploads for reliable transfer of large files
- Server-side processing automatically optimizes images (compression, resizing, format conversion)
- AWS S3 storage for 99.99% uptime and reliable delivery
- Multiple size variants automatically generated for responsive use cases
This approach handles the complexity of image optimization that many teams struggle with, ensuring that assets are always served in the most efficient format possible without manual intervention.
Developer Experience: Type-Safe Asset Usage
The CLI component of AssetStack creates a seamless developer experience:
- Project association via GitHub repo detection or an AssetStack key in a
.assetstack
file - Type generation that creates TypeScript definitions for all assets in the associated repository
- Import mechanism with a custom
<Image />
component from the AssetStack npm package
This creates a development experience where you get full IDE autocompletion for your assets and type safety to prevent typos or references to non-existent images. For example:
// Import the Image component from AssetStack
import { Image } from '@assetstack/react';
// Use it with autocomplete and type safety
const MyComponent = () => {
return (
<div className="hero-section">
{/* The editor will autocomplete all available image names */}
<Image src="hero-banner" className="w-full h-auto" />
<Image src="team-photo" width={800} quality="high" />
<Image src="logo" variant="dark" />
</div>
);
};
Beyond simple references, the AssetStack Image component offers additional features:
- Automatic responsive sizing based on viewport
- Format negotiation (WebP/AVIF for supporting browsers)
- Lazy loading with configurable thresholds
- Color mode variants (light/dark)
Implementation Challenges & Solutions
Handling SVG Assets
SVGs presented a unique challenge since they can be used both as images and as inline code. AssetStack handles this by:
- Offering two import methods:
<Image src="icon" />
and<SVG name="icon" />
- Cleaning SVGs with SVGO during upload for optimal file size
- Supporting dynamic property assignment for inline SVGs (colors, sizes, etc.)
Synchronization Strategy
Keeping local type definitions in sync with the remote repository was another challenge. The solution involves:
- Webhook notifications when assets change in the repository
- CLI command
assetstack sync
that developers can run to pull the latest definitions - CI integration that can automatically update types during the build process
Business Benefits
Beyond the technical advantages, AssetStack delivers several key business benefits:
- Reduced design-development handoff friction
- Improved page load performance through optimized assets
- Reduced development errors from incorrect asset references
- Centralized asset management across multiple projects
Future Development
While AssetStack already solves the core problems of asset management, there are several planned enhancements:
- AI-powered tagging and categorization
- Integration with design tools (Figma, Sketch) for direct export
- Advanced analytics on asset usage across projects
- Support for more asset types (3D models, videos, fonts)
Conclusion
AssetStack represents a practical solution to a common problem in web development. By focusing on the specific needs of both designers and developers, it bridges a gap that has traditionally caused friction in web projects.
The project also reinforced an important lesson: sometimes using familiar, "boring" technology allows you to focus on solving the actual problem rather than fighting with new tools. The T3 stack provided a solid foundation that allowed rapid development without sacrificing quality or performance.
While the source code remains proprietary, I hope this technical breakdown provides insight into the approach and architecture that made AssetStack successful.