| .claude | ||
| assets | ||
| config | ||
| lib | ||
| priv | ||
| test | ||
| .dockerignore | ||
| .formatter.exs | ||
| .gitignore | ||
| .tiltignore | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| Dockerfile.dev | ||
| gen_phoenix.sh | ||
| mix.exs | ||
| mix.lock | ||
| README.md | ||
| setup.sh | ||
| Tiltfile | ||
Listly - Your Life, But Organized
A Phoenix LiveView application for tracking places to visit and things to do. Finally, a list you'll actually finish.
Modern Design: Bold pink gradient theme designed for late teens/early twenties who want to actually do things, not just dream about them.
🚀 Quick Start for New Developers
Prerequisites
- Docker and Docker Compose installed
- Git
Option 1: Using Tilt (Easiest for Beginners) ⭐
Tilt gives you a visual dashboard to manage everything:
cd ~/Development/listly
tilt up
Then:
- Open http://localhost:10350 (Tilt dashboard)
- Click "db-create" button to create the database
- Click "db-migrate" button to run migrations
- Visit http://localhost:4000 to see your app
- Register an account - you'll get a registration email
- Check http://localhost:4000/dev/mailbox to confirm your email (see Email Setup below)
- Log in and start creating bucket lists!
Option 2: Using Docker Compose
cd ~/Development/listly
docker compose up
Then in another terminal:
docker compose exec app mix ecto.create
docker compose exec app mix ecto.migrate
Visit http://localhost:4000
Option 3: Local Development (Fastest Iteration)
If you have Elixir installed locally:
# Start only the database
docker compose up -d db
# Install dependencies
mix deps.get
# Create and migrate database
mix ecto.create
mix ecto.migrate
# Start Phoenix server
mix phx.server
# Or for interactive debugging
iex -S mix phx.server
Visit http://localhost:4000
📧 Email Confirmation (Important!)
When you register, the app sends a confirmation email. In development, emails don't actually send—they're stored locally:
- Register at http://localhost:4000
- View the email at http://localhost:4000/dev/mailbox
- Click the confirmation link in the email
- Log in with your account
This works because of the Local email adapter—perfect for development, no external services needed.
📚 Complete Documentation
For detailed information, see:
- CLAUDE.md - Complete development guide
- Elixir Basics - What is Elixir and LiveView?
- Common Commands - Useful CLI commands
- Troubleshooting - Solutions to common problems
📁 Project Structure
Here's what you'll find in the codebase:
listly/
├── assets/ # Frontend (CSS, JavaScript)
├── config/ # Application configuration
│ ├── config.exs # Base config (email, logging, etc.)
│ ├── dev.exs # Development settings
│ ├── prod.exs # Production settings
│ ├── runtime.exs # Environment variables
│ └── test.exs # Test environment
├── lib/
│ ├── listly/ # Business logic (core app)
│ │ ├── accounts/ # User authentication
│ │ ├── lists/ # Bucket lists domain
│ │ ├── social/ # Comments and reactions
│ │ └── ...ex # Context modules
│ └── listly_web/ # Web layer (UI, pages)
│ ├── components/ # Reusable UI components
│ ├── live/ # LiveView pages (interactive)
│ ├── router.ex # URL routes
│ └── ...
├── priv/repo/migrations/ # Database schema migrations
├── test/ # Test files
└── docker-compose.yml # Docker setup
Key Directories:
lib/listly/- Where the business logic lives (no UI)lib/listly_web/live/- Where the interactive pages live (LiveView)test/- Where you write tests
🛠️ Technology Stack
- Elixir 1.16.3 - Functional language on the Erlang VM
- Phoenix 1.7 - Web framework
- Phoenix LiveView - Real-time interactive pages without JavaScript
- PostgreSQL 16 - Database
- Tailwind CSS - Styling
- Docker - Development environment
- Tilt - Development orchestration
🔧 Common Commands
Running the App
# Start development server
mix phx.server
# Start with interactive shell (for debugging)
iex -S mix phx.server
# In Tilt UI
# Click the "app" resource and check logs
Database Commands
# Create database
mix ecto.create
# Run pending migrations
mix ecto.migrate
# Rollback last migration
mix ecto.rollback
# Reset database (careful! drops everything)
mix ecto.reset
# Create a new migration
mix ecto.gen.migration add_new_table
Testing
# Run all tests
mix test
# Run specific test file
mix test test/listly/lists_test.exs
# Run with coverage
mix test --cover
# With Tilt
# Click "run-tests" button in Tilt UI
Code Quality
# Format code (fixes indentation, spacing, etc.)
mix format
# Check if code is formatted
mix format --check-formatted
Dependencies
# Install/update dependencies
mix deps.get
# Clean and reinstall everything
mix deps.clean --all && mix deps.get
# Update dependencies to latest
mix deps.update --all
✨ Features
Implemented
- ✅ User authentication and registration
- ✅ Create and manage bucket lists
- ✅ Add places to lists with descriptions and links
- ✅ Share lists with other users (viewer/editor/admin roles)
- ✅ Public lists exploration
- ✅ Comments on lists and places (with threading)
- ✅ Reactions (like/dislike) on lists, places, and comments
- ✅ Role-based authorization (view/edit/admin/delete)
- ✅ Comprehensive test coverage (147 tests)
Planned
- ⬜ Member management UI (invite/remove users)
- ⬜ Drag-and-drop reordering for places
- ⬜ Image uploads for places
- ⬜ Search and filtering
- ⬜ User profiles
- ⬜ Activity feed
- ⬜ Email notifications
📚 Understanding the Stack
What is Elixir?
Elixir is a functional programming language that runs on the Erlang VM. Key concepts:
- Functional - Functions are the building blocks, data is immutable
- Pattern Matching - Destructure data elegantly without conditionals
- Pipes
|>- Chain function calls left to right - Concurrent & Scalable - Handles thousands of connections easily
Learning Resources:
What is Phoenix?
Phoenix is a web framework for Elixir. It handles:
- Routing - Map URLs to code
- Controllers - Handle HTTP requests
- Views - Render HTML/JSON
- Database integration - via Ecto
Documentation: Phoenix Framework
What is LiveView? (The Star ⭐)
LiveView is what makes this app special. Instead of traditional request/response:
- Server renders HTML - Fast initial page loads
- WebSocket connection - Real-time updates without page reload
- Stateful server - Server maintains component state
- Zero JavaScript needed - It's all Elixir!
Example: When you edit a bucket list, all connected browsers see the update instantly without refreshing.
Learn More: Phoenix LiveView Documentation
🐛 Troubleshooting
Port 4000 Already in Use
# Find the process using port 4000
lsof -i :4000
# Kill it
kill -9 <PID>
# Then try running the app again
Database Connection Error
# Check if database is running
docker compose ps
# View database logs
docker compose logs db
# Restart the database
docker compose restart db
"iex: command not found" or "mix: command not found"
Elixir is not installed on your computer. Either:
- Install Elixir locally - https://elixir-lang.org/install.html
- Or use Docker -
docker compose exec app iexinstead ofiex
Tests Fail in Docker
Make sure to set the environment:
docker compose exec app sh -c "MIX_ENV=test mix test"
Asset Compilation Issues
# Reinstall npm dependencies
cd assets
npm install
cd ..
# Recompile assets
mix assets.deploy
Dependencies Won't Install
# Complete clean reinstall
mix deps.clean --all
mix deps.get
mix compile
💡 Tips for New Elixir Developers
1. Read Error Messages Carefully
Elixir provides excellent error messages. The stack trace usually tells you exactly what went wrong and where.
2. Use the Interactive Shell
# Start IEx with your app loaded
iex -S mix
# Create test data
user = Listly.Accounts.create_user!(%{email: "test@example.com", password: "password"})
# Query the database
Listly.Repo.all(Listly.Lists.List)
# Test a function
Listly.Lists.authorize(:view, user, some_list)
3. Check the Logs
When something breaks, logs are your best friend:
# In Tilt UI - click "app" to see logs
# Or locally - watch your terminal where mix phx.server is running
# Or in Docker
docker compose logs -f app
4. LiveView is Your Best Tool
When building interactive features:
- Use LiveView for forms, real-time updates, modals
- Use LiveComponent for reusable UI pieces
- Use regular controllers only for simple static pages
5. Database Migrations Are Sacred
Always use migrations for schema changes:
mix ecto.gen.migration add_something_important
# Edit the generated file in priv/repo/migrations/
mix ecto.migrate
Never edit the database schema directly!
6. Write Tests (You'll Thank Yourself)
# Simple test example
test "create_list/2 creates a list" do
user = user_fixture()
{:ok, list} = Lists.create_list(user, %{name: "My List"})
assert list.name == "My List"
assert list.user_id == user.id
end
7. Use iex -S mix phx.server for Debugging
When you need to debug, use the interactive shell:
iex -S mix phx.server
# Then in your LiveView, you can trigger actions and inspect state
🧪 Running Tests
The project has 147 tests covering:
- Lists context (24 tests)
- Social context (14 tests)
- Authorization policies (15 tests)
- User authentication (94 tests)
Run all tests
With Tilt:
- Click "run-tests" in the Tilt UI
Locally:
mix test
With Docker Compose:
docker compose exec app sh -c "MIX_ENV=test mix test"
Run specific tests
# Test a specific file
mix test test/listly/lists_test.exs
# Run one test
mix test test/listly/lists_test.exs:42
# Test with coverage report
mix test --cover
📖 Learning Resources
Official Documentation
- Phoenix Framework - Framework homepage
- Phoenix Guides - Official guides
- Phoenix API Docs - Full API reference
- LiveView Documentation - LiveView guide
- Ecto Documentation - Database queries
- Elixir Documentation - Language reference
Interactive Learning
- Elixir School - Free, interactive lessons
- Exercism - Elixir Track - Practice problems
- Pragmatic Studio - Video course (paid, highly recommended)
Community & Help
- Elixir Forum - Ask questions, get answers
- Elixir Slack - Real-time chat with the community
- Stack Overflow - Tag:
phoenix-frameworkorelixir
Key Concepts Explained
- Pattern Matching - https://elixirschool.com/en/lessons/basics/pattern_matching
- Pipes - https://elixirschool.com/en/lessons/basics/pipe_operator
- Immutability - https://elixirschool.com/en/lessons/basics/collections
- Contexts - https://hexdocs.pm/phoenix/contexts.html
❓ Quick Questions?
Q: Where do I write my features?
A: New LiveView pages go in lib/listly_web/live/. Business logic goes in lib/listly/contexts.ex.
Q: How do I add to the database?
A: Create a migration with mix ecto.gen.migration name_here, then add the schema in lib/listly/.
Q: Why isn't my code running? A: Check the error message in your terminal. Mix errors are usually very clear about what's wrong.
Q: How do I debug something?
A: Use iex -S mix phx.server to get an interactive shell, then inspect values and test functions.
Q: How are users/lists stored?
A: In PostgreSQL database. Use mix test to verify everything works.
🚀 Next Steps
- ✅ Get the app running (you're here!)
- 📧 Confirm your email via
/dev/mailbox - 🪣 Create a bucket list
- 📖 Read CLAUDE.md for deeper understanding
- 🧪 Run tests to see what works:
mix test - 💻 Pick a feature from "Planned" and build it!
📝 License
Private project