A modern web application for sharing and managing code snippets, built with Go and Vue.js.
-
User Authentication & Authorization
- JWT-based authentication with refresh tokens
- Secure password hashing with bcrypt
- Session management with automatic cleanup
- Protected routes and middleware
-
Code Snippet Management
- Create, read, update, and delete snippets
- Rich snippet metadata (title, content, language, author)
-
Social Features
- Like and unlike snippets with real-time updates
- Save/bookmark snippets for later reference
- View liked and saved snippets in user profiles
-
User Profiles
- Complete user profile management
- Update username, email, and avatar
- Change password with current password verification
- View personal snippets, liked snippets, and saved snippets
-
Modern UI/UX
- Responsive design with mobile support
- Dark/light theme switching
- Loading states and error handling
- Toast notifications with Vue Sonner
- Form validation with Zod and VeeValidate
- Client-side caching with TanStack Query
-
Backend Architecture
- Clean architecture
- Type-safe database queries with SQLC
- Comprehensive error handling and logging
- RESTful API with proper HTTP status codes
POST /api/auth/login
- User loginPOST /api/auth/signup
- User registrationPOST /api/auth/logout
- User logoutPOST /api/auth/refresh
- Refresh access token
GET /api/snippets
- Get all snippetsGET /api/snippets/{id}
- Get a specific snippetPOST /api/snippets
- Create a new snippetPUT /api/snippets/{id}
- Update a snippetDELETE /api/snippets/{id}
- Delete a snippetPATCH /api/snippets/{id}/like?action=like|unlike
- Like or unlike a snippetPATCH /api/snippets/{id}/save?action=save|unsave
- Save or unsave a snippet
GET /api/users/{id}
- Get user by IDGET /api/users/{id}/snippets
- Get user's snippetsGET /api/users/{id}/liked
- Get user's liked snippetsGET /api/users/{id}/saved
- Get user's saved snippetsPATCH /api/users/{id}
- Update user profilePATCH /api/users/{id}/password
- Update user passwordPATCH /api/users/{id}/avatar
- Update user avatar
GET /api/users/me
- Get current user's profileGET /api/users/me/snippets
- Get current user's snippetsGET /api/users/me/liked
- Get current user's liked snippetsGET /api/users/me/saved
- Get current user's saved snippetsPATCH /api/users/me
- Update current user's profilePATCH /api/users/me/password
- Update current user's passwordPATCH /api/users/me/avatar
- Update current user's avatar
The backend follows a clean architecture pattern:
- Domain Layer: Core business logic and entities
- Repository Layer: Data access interfaces and implementations
- API Layer: HTTP handlers, DTOs, and request/response handling
- Server Layer: Routing, middleware, and server configuration
- Storage Layer: Database operations with SQLC for type-safe queries
Key Design Patterns:
- Repository pattern for data access
- Dependency injection for loose coupling
- Middleware pattern for cross-cutting concerns
- Clean separation of concerns between layers
The frontend is built with modern Vue.js practices:
- Vue 3 Composition API: Modern reactive programming
- TypeScript: Type safety throughout the application
- Vite: Fast build tooling and development server
- Tailwind CSS: Utility-first styling with custom design system
- Pinia: State management with TypeScript support
- TanStack Query: Server state management and caching
- VeeValidate + Zod: Form validation with schema validation
- Vue Router: Client-side routing with navigation guards
Component Architecture:
- Atomic design principles
- Reusable UI components with shadcn/ui
- Composition-based component logic
- Proper TypeScript interfaces and types
- Go 1.24+: High-performance server language
- SQLite: Lightweight database with SQLC
- Chi Router: Lightweight HTTP router
- Gorilla/WebSocket: WebSocket implementation
- JWT: JSON Web Tokens for authentication
- bcrypt: Password hashing
- Zap: Structured logging
- Docker: Containerization
- Vue 3: Progressive JavaScript framework
- TypeScript: Type-safe JavaScript
- Vite: Build tool and dev server
- Tailwind CSS: Utility-first CSS framework
- Pinia: State management
- TanStack Query: Data fetching and caching
- VeeValidate: Form validation
- Zod: Schema validation
- Lucide Vue: Icon library
- SQLC: Type-safe SQL code generation
- Air: Live reload backend for development
- ESLint: Code linting
- Prettier: Code formatting
- pnpm: Fast package manager
The application uses SQLite with the following main tables:
- users: User accounts and profiles
- snippets: Code snippets with metadata
- user_likes: Many-to-many relationship for snippet likes
- user_saves: Many-to-many relationship for saved snippets
- sessions: User session management
- Go 1.24 or later
- Node.js 22.x or later
- pnpm (recommended) or npm
- Docker and Docker Compose (optional)
-
Install Go dependencies:
go mod download
-
Prepare database
mkdir data
SEED=true go run .
- Run the server:
# Using Air for hot reload air # Or directly go run .
-
Install dependencies:
cd frontend pnpm install
-
Start development server:
pnpm dev
-
Build for production:
pnpm build
In development, the backend server proxies requests to the Vite development server. You can access the application at:
- Frontend: http://localhost:8080
- Backend API: http://localhost:8080/api
The backend automatically forwards frontend requests to the Vite dev server running on port 5173, so you only need to access the application through the backend port (8080).
When working on database schema changes or migrations, it's recommended to use an in-memory database instead of a file-based database for faster development iterations. You can set this up by:
-
Using SQLite in-memory mode:
DB_PATH=":memory:" go run .
DB_PATH=":memory:" air
-
Or modify the environment variable:
export DB_PATH=":memory:"
This approach provides:
- Faster database operations
- No file I/O overhead
- Automatic cleanup between runs
- Easier testing and development
For production deployment, you can serve the built frontend files directly from the backend by setting the SERVE_STATIC=true
environment variable. This eliminates the need for a separate frontend server and proxy configuration.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.