Claude Code productivity tips
Getting started with Claude Code is super simple.
Once you've made yourself familiar with it, you may want to improve your workflow.
Here are a few quick tips that are relevant to most users.
Keyboard Shortcuts
There are lots of keyboard shortcuts. Here are the most relevant ones.
- Insert a Newline
- To add a newline without submitting your prompt, use
Alt+Enter.
You can configure some terminals to supportShift+Enterthrough/terminal-setup, but this d...
Tracking External API Performance in Rails Logs
When an LLM is part of a request, you want to keep track of how much of the runtime was spent waiting on it, how many calls it took, and the ratio of input to output tokens without opening a debugger every time. Passively watching these numbers catches prompt bloat, runaway tool-call loops, and regressions from model changes just by scrolling the log. The same pattern applies to any slow external API you want visibility on.
Hooking into Rails' controller instrumentation allows us to get additional information like this in every log line:
...
A restrictive (but still practicable) CSP for Rails projects
Below is a strict, but still workable Content Security Policy for your Ruby on Rails project. Use this CSP if you want to be very explicit about what scripts you allow, while keeping pragmatic defaults for styles, images, etc. This CSP does not use the viral strict-dynamic source (reasoning).
We also have a very compatible CSP which is more liberal. Compatibility might outweigh strictness if you have a lot of scripts you can...
Sending newsletters via rapidmail with SMTP and one-click unsubscribe
If you need to implement newsletter sending, rapidmail is a solid option.
Support is very fast, friendly and helpful, and the initial setup is simple. Since rapidmail works via SMTP, you can simply ask the Ops team to configure SMTP credentials for your application.
You also do not need to use rapidmail’s built-in newsletter feature. Instead, you can send emails as transactional mails, which allows you to keep the entire newsletter logic inside your application.
One thing to keep an ey...
Controlling the order of DOM event listeners
Event listeners are called in the order of their registration:
button.addEventListener('click', () => console.log("I run first"))
button.addEventListener('click', () => console.log("I run second"))
Sometimes you want a listener to always run first (or last), but have no control over the order in which other listeners are registered.
There is no clean mechanism in the DOM API for this. This card shows some hacks to do it anyway.
Find conflicting listeners
You can see the order of registered DOM event listeners usi...
Working with lists of DOM elements in JavaScript
When you query the browser for DOM elements, there are some footguns you should know about.
Some lists are synchronized with the DOM
Some DOM APIs return live lists that automagically update their contents as the underlying DOM is manipulated.
Example
Let's assume we have two <div> elements:
<div id="one"></div>
<div id="two"></div>
We have multiple ways to retrieve a list of these elements. At first glance, they all look the same:
let liveList = element.getElementsByTagName('div')
let nonLiveList = docum...
Git: Finding changes in ALL commits
Finding changes
When you're looking for a specific change in Git, there are multiple axes you can choose:
-
git log -- path/to/filelists all commits that touch a file -
git log -G some_stringlists all commits where the diff contains "some_string"
Note that you can do most of these things with Git tools as well, e.g. tig path/to/file.
Considering ALL commits
By default, only the current branch (HEAD) is searched. To search across the entire local repository, add these options:
-
--all: Search all known refs (branches...
Making minimal updates to DOM trees using morphdom / idiomorph
When you replace parts of the DOM with new HTML, using .innerHTML = newHtml is usually the simplest and fastest option. It comes at the price of your DOM elements losing state, like input values, scroll position, progress in a video player, or even more complex state for custom elements.
One option to avoid this are libraries like morphdom (as used by Phoenix Liveviews) or idiomorph (as used by Rails' Turbo).
It lets you write
morphdo...
GoodJob: Ensure you get notified about background exceptions
GoodJob and ActiveJob rescue exceptions internally, preventing exception_notification from triggering. This can cause silent job failures.To get notified, subscribe to ActiveJob events and configure GoodJob's on_thread_error hook. This lets you manually call your exception notifier for every retry, discard, or internal GoodJob error.
# config/initializers/good_job.rb
# Manually notify on job failures, as they are handled internally by ActiveJob/GoodJob.
ActiveSupport::Noti...
Improve accessibility with [aria-required] in SimpleForm
SimpleForm comes with an option browser_validations which could be used to give fields that have a presence validation the HTML required attribute. We usually turn it off due to difficulties controlling its behavior and appearance. Instead we only mark required fields with an asterisk (*) next to its label. Blind users probably only discover the validation issue after submitting the form due to the now displayed error messages.
A compromise with better acce...
How to auto-resize a textarea (or other inputs) in pure CSS
Modern CSS offers the field-sizing property to allow elements to automatically adjust size (width and/or height) to fit their contents.
The most common use case are textareas which start fairly small (e.g. 2 or 3 rows tall) but grow when users enter longer text.
Usage
textarea {
field-sizing: content;
}
That's it! At least in modern Chromium-based browsers.
Limited browser support
Support is still lacking in Firefox and Safari (as of mid 2025)....
Adding comments to ambiguous database columns
The DB schema is the most important source of truth for your application and should be very self-explanatory. If determining the true meaning of a DB column requires historical research in your issue tracker or reverse engineering of your source code you might consider adding a comment.
Both PostgreSQL and MySQL support comments in the DB schema:
- For new columns: https://guides.rubyonrails.org/active_record_migrations.html#comments
- Changing the comment for existin...
How to: Self-hosted fonts via NPM packages
We usually ship applications that self-host webfonts to comply with GDPR.
Many popular web fonts are available as NPM packages provided by Fontsource.
We recommend using those instead of downloading and bundling font files yourself. (See below for a list of benefits.)
Usage
- Go to fontsource.org and search for the font you want to add (or a font that suits your application).
- Click the font card to vie...
Better performance insights with gem `rails_performance`
Even if you don't make any beginner mistakes like N+1 queries or missing DB indices, some requests can have bad performance. Without good performance metrics, you probably won't notice this until it's too late.
We investigated multiple gems and found that rails_performance (https://github.com/igorkasyanchuk/rails_performance) provides a lot of valuable information with very little setup cost. It only needs Redis which we use in the majority of our applications anyw...
Controlling smooth scrolling in browsers
It can be hard to understand what causes a browser scroll smoothly or instantly. CSS, JavaScript and the browser settings all have options to influence the scroll behavior. They all interact with each other and sometimes use the same words for different behavior.
CSS
Scrolling elements can use the scroll-behavior CSS property to express a preference between smooth and instant scrolling.
Preferring instant scrolling
CSS can prefer instant scrolling behavior:
html {
scroll-behavior: auto; /* the default */
}
An `aut...
Testing Accessibility using Orca
Orca is a Linux screen reader. Since it is part of the GNOME project it should come preinstalled with Ubuntu installations.
Getting started
To turn on the screen reader you can either go to Settings > Accessibility and then activate Screen Reader in the "Seeing" section or you can simply type orca in your terminal. Alternatively you can use the default keyboard shortcut super + alt + s to toggle the screen reader.
Note
It may feel quite strange in the beginning to use a screen reader. It is constantly commenting on everyth...
Rails: Configuring the default sorting behaviour
In Rails, the implicit_order_column (added in Rails 6) is a configuration option that helps you define the default sorting behavior of ActiveRecord queries when no explicit ORDER BY clause is provided. This option allows you to specify a column that Rails will use to automatically sort records in a particular order when no specific ordering is given.
Since the id is typically the primary key and automatically indexed, Rails will default t...
Implementing upload progress and remove button with ActiveStorage DirectUpload
DirectUpload allows you to upload files to your file storage without having to wait for the form to submit. It creates AJAX requests to persist the file within your form and wraps them in a little API. This card will show you how to use it in order to create in-place file uploads with progress and a remove button.
This is basic functionality, you may add additional elements, styles and logic to make this look fancy, but the core functionality is the same. I created a file upload that looks like this:

const svgo = require('svgo')
const options = {
// ...
loader: {
// ...
'.svg': 'copy', // this may be different...
Overview of method delegation in Rails
Method delegation in Rails can help you to keep your code organized and avoid deep call chains (law of demeter) by forwarding calls from one object to another. Rails provides several ways to accomplish this. Below is a concise overview of the most common approaches:
Single-Method delegation with delegate
Use the built-in delegate method from ActiveSupport to forward specific methods:
class User < ApplicationRecord
has_one :profile
delegate :full_name, :age, to: :profile, prefix: true
end
- `delegate: full_name, :age...
Debug your Postgres SQL query plan
When debugging slow SQL queries, it’s helpful to understand the database engine's query plan. Whenever you execute a declarative SQL query, the database generates a "query plan" that outlines the exact steps the engine will take to execute the query. Most of the time, we don’t need to worry about this plan because SQL engines are highly optimized and can generate efficient execution strategies automatically. However, if a query is slow, inspecting the generated plan can help identify bottlenecks and optimization opportunities.
If you're usi...
How to disable telemetry for various open source tools and libraries
Hint
If you are using our opscomplete.com hosting we can set all environment variables mentioned below for your deployment on request.
If you're lucky DO_NOT_TRACK=1 opts you out of CLI telemetry - it's not widely adopted. When you're using any of the libraries below, I'd rather opt out explicitly:
Yarn
https://yarnpkg.com/advanced/telemetry (Since: Version 2.2)
Disable for a project:
#...
How the Date Header Affects Cookie Expiration and Caching
tl;dr
When a cookie includes an
Expiresattribute or an HTTP response includes caching headers likeExpiresorCache-Control, their validity depends on the server'sDateheader if present. Otherwise, the browser uses its local time. This can lead to issues in tests with mocked time or inconsistent cache behavior.
Cookie Expires depends on the Date header or browser time
When a cookie includes an Expires attribute, the browser evaluates the expiration date relative to a reference time:
- If the HTTP response ...