Judder  ·  haptic design for iOS

Haptics you can see.

Judder is a native iOS app for designing Core Haptics patterns on a timeline. Events chain on one axis, sound sits underneath them on that same axis, and what leaves is AHAP or a Swift function you paste into your project. It runs on the phone in your hand, so the pattern you draw is the pattern you feel.

Download on the App Store See the editor iOS 17 · iPhone with a Taptic Engine
50events
49burst hits
1.60 sspan
50 / 512budget

This is the real resolver, not a drawing of one. Gap is measured from the previous event's start, so a burst can sit on top of the bed it rides. That overlap is the thing a list of numbered rows can never show you. Every sweep here takes the same two seconds, so four of the five run below real time and the transport says by how much. Every number on the axis is the real one.

Every default in the starter set is checked against published psychophysics, and the papers are cited at the bottom of this page.

The state of things

Most haptics are guessed at.

Core Haptics is a capable API attached to a workflow that has never really existed. The haptic authoring landscape is scattered enough that a 2026 CHI paper had to build a taxonomy before the available tools could even be compared with each other.[1] On iOS the practical result is that most apps ship two taps and a success buzz, because that is all anyone can be confident in.

01

AHAP is JSON you write by hand

Fifty transients means fifty objects with a time key you increment yourself. One typo in a parameter name and the event silently does nothing.

02

The Simulator has no Taptic Engine

Every edit costs a build and a deploy to feel. So the loop is slow, and a slow loop means you stop at the first thing that is not obviously wrong. Adding tactile feedback is worth doing well: it moved touchscreen text entry close to physical keyboard performance in a controlled study.[3]

03

Time is invisible

Intensity, sharpness, duration and gap are four numbers with no picture. You author temporal density without ever seeing density. Give animators an object they manipulate directly instead of per-actuator values and both experts and novices prefer it.[2]

The app

The editor is a canvas. The preview is the device.

Three tabs and one editor. Patterns are yours and they persist. Open one and it pushes, with the tab bar giving way to a transport. Anything you change plays back on the phone you are holding, in about the time it takes to lift your thumb.

  • CanvasLanes on one time axis. Block height is intensity, width is duration, and a burst draws as its real comb of hits at its real step.
  • InspectorA sheet at three detents. Drag it down and the canvas goes full bleed. Drag a parameter and the shape moves under your finger, which matters because amplitude discrimination follows Weber's law: equal steps in the number are not equal steps in sensation.[4]
  • TransportPlay, plus a span and event count that stay live while you drag. The playhead sweeps and each event lights as it passes.
  • SoundAn audio bed on its own lane, opened from the lane that draws it rather than buried in settings.

Live app, embedded. Drive it.

What it does

Six things, done properly.

Chain

Events in sequence

Transients, continuous events and bursts on one line. Reorder by drag. Gap is relative to the previous start, so overlapping is a first class move rather than an accident.

Burst

One control, many hits

Set a duration and a step and Judder expands the comb for you, clamped against the real ceiling. Drag the step and watch the comb rebuild in place. The starter textures step at 33 and 35 ms, above the roughly 25 ms interval at which two pulses stop being two,[5] which is why grain reads as grain instead of as a buzz.

Envelope

Attack, decay, release

Continuous events carry a curve, and the block is clipped to its own silhouette. What is drawn is what the engine will run. Under about 30 ms a stimulus is felt as a discrete pulse rather than a vibration, and that boundary holds from 40 to 590 Hz,[6] so a short continuous event is really a transient wearing a duration.

Sound

An audio layer that lines up

Drop a bed under the haptic lane on the same time axis. Sound is a layer here, not a settings screen, because a hit and its sample either agree or they do not. Audiotactile binding is frequency specific, and strongest in the 200 to 390 Hz band where skin is most sensitive.[7]

Validate

Know before you ship

Resolved event count against the budget, burst hits against the cap, total span, and the specific warnings that bite. No surprises at runtime.

Export

AHAP or Swift

Take the pattern file, or take a generated Swift function with the loop already written. Copy it out and build. Nothing you ship links back to Judder.

Export

It leaves as code you own.

Judder is a design tool, not a framework. Nothing it produces links against it. You get a pattern file or a function, plus the report that tells you it will hold.

// DensityBed.ahap  ·  50 events  ·  1.60 s
{
  "Version": 1,
  "Pattern": [
    { "Event": {
        "Time": 0,
        "EventType": "HapticContinuous",
        "EventDuration": 1.6,
        "EventParameters": [
          { "ParameterID": "HapticIntensity", "ParameterValue": 0.70 },
          { "ParameterID": "HapticSharpness", "ParameterValue": 0.10 }
        ]
    }},
    { "Event": {
        "Time": 0,
        "EventType": "HapticTransient",
        "EventParameters": [
          { "ParameterID": "HapticIntensity", "ParameterValue": 0.55 },
          { "ParameterID": "HapticSharpness", "ParameterValue": 0.75 }
        ]
    }},
    // 48 more transients at 0.033 s intervals
    { "Event": {
        "Time": 1.584,
        "EventType": "HapticTransient",
        "EventParameters": [
          { "ParameterID": "HapticIntensity", "ParameterValue": 0.55 },
          { "ParameterID": "HapticSharpness", "ParameterValue": 0.75 }
        ]
    }}
  ]
}
50events resolved
49burst hits
1.60 sspan
50 / 512engine budget
One warning. A 1.60 s loop restarts the audio bed on every cycle, so the sample needs a seamless tail or the loop will click.

Recipes

Start from a pattern, not from zero.

Judder ships a starter set of the haptics an app actually needs. Open one and take it apart. Save your version over the top. These are the four you will reach for first, and their step and duration values sit where they do for the reasons cited below.

Straight answers

What it is, and what it is not.

Engine event budget
512
Burst hits per event
256
Transient playback tail
0.08 s
Minimum iOS
17.0
Written in
Swift, SwiftUI
Runtime dependencies
none
Where to get it
App Store
Needs an account
no
Sends your patterns anywhere
no
Works on iPad
not yet
Plays haptics in the Simulator
no hardware
Replaces Core Haptics
no

The right column is what Judder does not do. It is printed here rather than left to be found out afterwards.

Provenance

Where the numbers come from.

A tool that ships defaults should be able to show its work. Judder's are not taste. The burst step sits where it does because of a measured fusion threshold. The shortest continuous event worth authoring is bounded by a duration threshold, and the sound lane shares the haptic time axis because audiotactile binding turns out to be frequency specific. Every paper behind those choices is listed here, along with what it was used for.

  1. [1] Juliette Regimbal, Cyan Kuo, and Jeremy R. Cooperstock. Understanding Haptic Authoring Tools through a Taxonomy and Descriptive Analysis. Proceedings of the 2026 CHI Conference on Human Factors in Computing Systems, Barcelona, April 2026. doi:10.1145/3772318.3790575  ·  companion catalogue Used for the claim that haptic authoring has no settled workflow. The authors gather the field's authoring tools and build a taxonomy so that the tools can be described and compared at all.
  2. [2] O. Schneider, A. Israr, and K. E. MacLean. Tactile Animation by Direct Manipulation of Grid Displays. Proceedings of the 28th Annual ACM Symposium on User Interface Software and Technology, Charlotte, 2015. doi:10.1145/2807442.2807470 Used for the case for a timeline canvas over a list of rows. The paper starts from the premise that animators are already expert in time and space, and its evaluation found experienced and novice animators alike preferred a directly manipulated object to setting actuator values.
  3. [3] E. Hoggan, S. A. Brewster, and J. Johnston. Investigating the effectiveness of tactile feedback for mobile touchscreens. Proceedings of CHI 2008, pages 1573 to 1582. doi:10.1145/1357054.1357300 Used for whether haptics repay the effort at all. Adding tactile feedback to a touchscreen significantly improved finger based text entry, bringing it close to the performance of a physical keyboard.
  4. [4] E. Francisco, V. Tannan, Z. Zhang, J. Holden, and M. Tommerdahl. Vibrotactile amplitude discrimination capacity parallels magnitude changes in somatosensory cortex and follows Weber's Law. Experimental Brain Research 191(1), 2008, pages 49 to 56. doi:10.1007/s00221-008-1494-6 Used for why intensity is a shape you drag rather than a number you type. Amplitude discrimination scales with the size of the stimulus, so a step of 0.05 near the top of the range is not the step it is near the bottom.
  5. [5] Linda Petrosino and Donald Fucci. Temporal resolution of successive brief stimuli for the tongue and hand. Bulletin of the Psychonomic Society 22, 1984, pages 208 to 210. doi:10.3758/BF03333807 Used for the burst step defaults. Two pulse fusion thresholds were measured at 24.63 ms on the tongue and 24.73 ms on the thenar eminence of the hand. Judder's starter textures step at 33 and 35 ms, which keeps them on the countable side of that boundary.
  6. [6] Byron Remache-Vinueza, Andrés Trujillo-León, and Fernando Vidal-Verdú. Vibrotactile stimulus duration threshold for perception of pulse to vibration transition. Scientific Reports, 2025. doi:10.1038/s41598-025-85778-6 Used for the shortest continuous event worth authoring. Participants reported the change from a discrete pulse to a vibration at about 30 ms, and that threshold stayed roughly constant from 40 to 590 Hz, which is not what the equivalent auditory result does.
  7. [7] Evagoras Xydas, Banu Abdikadirova, and Nurgeldy Praliyev. Audiotactile integration in the Pacinian corpuscle's maximum sensitivity frequency range. Attention, Perception, and Psychophysics 82, 2020, pages 3250 to 3257. doi:10.3758/s13414-020-02025-y Used for putting the audio bed on the haptic time axis instead of in a settings screen. Vibration at a matching frequency let participants detect tones that were otherwise inaudible, and the effect held across 200 to 390 Hz, where the skin's Pacinian channel is most sensitive.

These papers were not written about Judder and do not endorse it. They are the published work its defaults were checked against. Where there is no literature behind a number, the page says so: the 512 event budget, the 256 hit burst cap and the 0.08 s transient tail are limits taken from the app's own engine, not findings from a journal.

judder-haptics.com

Your browser cannot feel this. Your phone can.

Judder is on the App Store. If you ship an iOS app and you have ever settled for a default impact generator because the real thing was too slow to iterate on, this was built for you.