Why Slack built an in-app image editor

More than 70% of files uploaded to Slack are images, and over 75% of those are screenshots. Screenshots tend to be short-lived but carry important context, and users often need to tweak them before sharing. Previously, that meant leaving Slack and opening a separate image tool, costing time and breaking focus. To address that friction, Slack built a simple image editor supporting rotation, cropping, and flipping directly in the app.

The project also served as the basis for an engineering internship, and the lessons from building it apply well beyond this single feature.

Thinking like a product engineer

Feature work can easily become consumed by implementation details. A few principles help keep the focus on the people who will actually use the feature:

  • Always return to the problem you set out to solve. It is easy to become attached to a solution and lose sight of the original user need, so take time to consider how people engage with the product and what their experience might be.
  • When facing a design tradeoff, test multiple options. A/B testing provides observable data instead of relying on guesswork.
  • Support decisions with logs and usage data. Tracking usage frequency, consistency, and user segments helps validate whether a feature is working as intended.

Shipping code into a shared codebase

The first feature targeted was a rotation button in the image viewer, chosen to deliver value quickly. Writing code for a large existing system is different from coding in a personal project; a seemingly straightforward feature requires care to integrate cleanly with what is already there. Key takeaways from the process were:

  • Follow existing interfaces and maintain consistency to avoid future conflicts.
  • Write code others can read and extend. Future-proofing means making room for new features without rewriting.
  • Reuse functions and objects wherever possible so fixes apply in one place instead of many.
  • Keep accessibility and localization in mind. All user-facing strings must be translated, and the feature has to work for all users.
  • Put new code behind a feature flag or experiment. This allows the code to be turned off quickly, and supports rolling out to specific groups gradually.

The transition from a personal coding style to one that fits a shared, maintainable codebase took several attempts. Mandatory code reviews played a major role; mentors were patient and the process taught a great deal. The final image editor took roughly two months of iteration while also learning two new languages.

Much of the difficulty was not strictly about code. Cropping raised questions about removing old cropped portions from public access, and exposing a public API endpoint required care so that no user input could overload servers or retrieve unauthorized data. Security, privacy, and compliance had to stay in balance alongside the feature logic. This experience reinforced that a good software engineer is defined by decision-making and tradeoff evaluation, not just coding speed.

Final takeaways

Deploying the finished feature was satisfying in a way that highlighted why the work matters: small code changes can affect millions of people. For anyone starting an internship or similar role, the advice is straightforward. Make mistakes, ask questions, and learn from the people around you. The right environment is one where the work is engaging every day and the mission feels worthwhile.