Collect feature requests, bug reports, and internal ideas with threaded comments, voting, image uploads, and status updates. No third-party platform required.
Use any email to sign up. Include +admin in your email to see the admin dashboard e.g. [email protected]
Demo resets every 10 minutes, so you can play around without breaking anything
Don't just read about Alto. Jump into the live demo and see how it feels. It's running on Heroku with full functionality.
Create tickets, add comments, vote on stuff, manage boards, poke around the admin interface. It's all there, running in a real Rails app.
Launch demo appQuick preview, but the live demo is way more fun to play with.
Alto's main interface: tickets, voting, comments, and status management. All natively integrated in your Rails app.
Most feedback tools make you send users to some external platform. Alto gives you everything you need to collect and manage product input right inside your app.
Your data, your users, your app. No third-party SaaS dependency.
Each board gets its own status workflow and tagging system for perfect organization.
Rich discussions with upvoting
Card view or forum-style list view
Polymorphic architecture that doesn't care what you call your users
Devise, custom auth, or public access. Whatever you're using.
Upload images in tickets and comments. Works with Cloudinary, S3, or local storage.
Connect to Slack, webhooks, analytics, and any external service with zero config.
Manage boards, track engagement, and get insights on feedback trends.
Alto is built for Rails devs who want full control and flexibility.
# Devise works automatically
config.permission :can_create_tickets? do
user_signed_in?
end
# Custom auth
config.permission :can_create_tickets? do
current_user.present?
end
# Public feedback
config.permission :can_create_tickets? do
true
end
# Configure any user model
Alto.configure do |config|
config.user_model = "Account"
config.user_display_name do |user_id|
Account.find(user_id)&.full_name || "Anonymous"
end
end
Switch between card view for visual browsing and list view for a forum-like experience
Card view shown here. Visual, Pinterest-style layout perfect for quick scanning. Users can also switch to list view for a forum-style experience.
Feature | Included |
---|---|
Multiple boards with customizable statuses and tagging | ✅ |
Voting system with upvotes | ✅ |
3-level threaded comments | ✅ |
Admin dashboard with analytics | ✅ |
Powerful callback hook system (Slack, webhooks, custom integrations) | ✅ |
Authentication-agnostic design (works with any auth system) | ✅ |
Custom fields per board (dropdowns, text inputs, multiselect, etc.) | ✅ |
Full-text search | ✅ |
Configurable status sets | ✅ |
Multiple view options (card & list/forum view) | ✅ |
Polymorphic user architecture (works with any user model) | ✅ |
Image upload support for tickets and comments (Cloudinary, S3, local storage) | ✅ |
Alto's callback system gives you deep integration power. Connect to any service with zero configuration. Just define the methods you need.
ticket_created(ticket, board, user)
ticket_status_changed(ticket, old_status, new_status, board, user)
comment_created(comment, ticket, board, user)
comment_deleted(comment, ticket, board, user)
upvote_created(upvote, votable, board, user)
upvote_removed(upvote, votable, board, user)
def ticket_created(ticket, board, user)
channel = board.slug == 'bugs' ? '#dev-team' : '#product'
SlackWebhook.post(
channel: channel,
text: "New #{board.name}: #{ticket.title}",
user: user&.email
)
end
def comment_created(comment, ticket, board, user)
SlackWebhook.post(
channel: '#feedback',
text: "💬 New comment on: #{ticket.title}",
blocks: [{
type: "section",
text: { type: "mrkdwn", text: comment.content }
}]
)
end
Three steps to get Alto running in your Rails app
Install the Alto gem from GitHub
Create tables and config file
Add to routes and customize permissions
# 1. Add to your Gemfile
gem 'alto', github: 'CG3-Media/alto'
# 2. Install and generate
bundle install
rails generate alto:install
# 3. Add to config/routes.rb
mount Alto::Engine => "/feedback"
Alto.configure do |config|
# Works with any authentication system
config.permission :can_access_alto? do
user_signed_in? # Devise
# current_user.present? # Custom auth
# true # Public access
end
config.permission :can_access_admin? do
current_user&.admin?
end
# Enable image uploads (requires ActiveStorage)
config.image_uploads_enabled = true
# Customize user display
config.user_display_name do |user_id|
User.find(user_id)&.name || "Anonymous"
end
end