# How to Manage Clip Trimming with Millisecond-Accurate Timing Precision in Clypra

> Learn to manage clip trimming with millisecond-accurate timing precision in Clypra. Explore how Clypra normalizes and ripple-edits clip timing for precise control.

- Repository: [Abdulkabir Musa/Clypra](https://github.com/AIEraDev/Clypra)
- Tags: how-to-guide
- Published: 2026-07-16

---

**Clypra stores clip timing as IEEE-754 floating-point seconds and enforces millisecond precision through the `trimIn` and `trimOut` fields, normalized by `normalizeClipTiming` in [`timelineClip.ts`](https://github.com/AIEraDev/Clypra/blob/main/timelineClip.ts) and ripple-edited via `rippleTrimClip` in [`timelineStore.ts`](https://github.com/AIEraDev/Clypra/blob/main/timelineStore.ts).**

Clypra is an open-source video editing framework that treats time as a continuous floating-point value, enabling frame-level and millisecond-level precision when managing clip trimming. Unlike editors that round to nearest frames, Clypra's architecture allows you to trim clips to exact millisecond boundaries using the `trimIn` and `trimOut` properties stored in the timeline state. This approach ensures that every trim operation maintains the invariant `duration === trimOut - trimIn` regardless of zoom level or playback resolution.

## Understanding Millisecond-Accurate Timing Storage

Clypra represents all temporal values as `number` types (JavaScript's IEEE-754 double-precision floating-point), where one second equals `1.0` and one millisecond equals `0.001`. This storage method provides sub-second precision out of the box without requiring specialized integer scaling or rational number libraries.

### The trimIn and trimOut Fields

According to the type definitions in [`src/types/index.ts`](https://github.com/AIEraDev/Clypra/blob/main/src/types/index.ts), every clip contains two critical fields that drive trimming:

- **`trimIn`**: The offset in seconds from the start of the source media to the first visible frame
- **`trimOut`**: The offset in seconds from the start of the source media to the last visible frame

These values are stored as raw numbers and can accept fractional values down to the millisecond level (e.g., `0.125` for 125 milliseconds).

## Core Trimming Implementation

The mathematical integrity of trim operations is maintained in [`src/lib/timeline/timelineClip.ts`](https://github.com/AIEraDev/Clypra/blob/main/src/lib/timeline/timelineClip.ts), which provides utility functions that enforce Clypra's timing invariants.

### Normalizing Clip Timing

When a clip is created or modified, the `normalizeClipTiming` function (lines 21-40 in [`timelineClip.ts`](https://github.com/AIEraDev/Clypra/blob/main/timelineClip.ts)) clamps `trimIn` and `trimOut` to valid ranges and recomputes the clip's duration:

```typescript
// Pseudocode representation of the normalization logic
const normalizeClipTiming = (clip, sourceDuration) => {
  clip.trimIn = Math.max(0, Math.min(clip.trimIn, sourceDuration));
  clip.trimOut = Math.max(clip.trimIn, Math.min(clip.trimOut, sourceDuration));
  clip.duration = clip.trimOut - clip.trimIn; // Enforces millisecond precision
};

```

This guarantees that `duration` always equals `trimOut - trimIn`, even when the source media length is unknown or when users drag trim handles by fractional amounts.

### Calculating Visible Duration

To retrieve the actual playable length of a trimmed clip, use the `getClipVisibleDuration` helper (lines 15-19 in [`timelineClip.ts`](https://github.com/AIEraDev/Clypra/blob/main/timelineClip.ts)). This function returns the difference between `trimOut` and `trimIn`, ensuring that any code consuming clip data receives the precise millisecond-accurate duration.

## Performing Ripple Trims

For professional editing workflows, Clypra implements ripple editing through the `rippleTrimClip` method in [`src/store/timelineStore.ts`](https://github.com/AIEraDev/Clypra/blob/main/src/store/timelineStore.ts) (lines 857-910). This function adjusts a clip's trim points while automatically shifting downstream clips to preserve timeline gaps or eliminate overlaps.

### Left-Side vs Right-Side Trimming

The `rippleTrimClip` method accepts three parameters:

1. **`clipId`**: The unique identifier of the target clip
2. **`side`**: Either `"left"` or `"right"` indicating which edge to trim
3. **`deltaTime`**: The time change in seconds (positive to extend, negative to shorten)

The implementation follows this sequence:

1. Computes the desired new duration as `clip.duration + deltaTime`
2. Adjusts `trimIn` (for left-side) or `trimOut` (for right-side) by the specified delta
3. Updates the clip's `duration` to `trimOut - trimIn`
4. Propagates the `deltaTime` value to every subsequent clip on the same track

Because `deltaTime` accepts floating-point values like `0.030` (30 milliseconds), you can perform ripple edits with millisecond accuracy.

## Practical Code Examples

### Setting Trim Points Manually

To programmatically set a clip's trim points to exact millisecond values:

```typescript
import { useTimelineStore } from '@/store/timelineStore';

const clipId = 'c123';
const newTrimIn = 0.125;   // 125 milliseconds
const newTrimOut = 5.000;  // 5 seconds

useTimelineStore.getState().updateClip(clipId, {
  trimIn: newTrimIn,
  trimOut: newTrimOut,
});

```

### Performing a Ripple Trim

To extend a clip's right edge by 30 milliseconds while shifting subsequent clips:

```typescript
import { useTimelineStore } from '@/store/timelineStore';

// Extend clip "c123" by 30ms at the right edge
useTimelineStore.getState().rippleTrimClip('c123', 'right', 0.030);

```

To shorten a clip from the left side by 15 milliseconds:

```typescript
useTimelineStore.getState().rippleTrimClip('c123', 'left', -0.015);

```

### Verifying Visible Duration

To confirm the precise duration after trimming:

```typescript
import { getClipVisibleDuration } from '@/lib/timeline/timelineClip';

const clip = useTimelineStore.getState().clips.find(c => c.id === 'c123')!;
console.log('Visible duration:', getClipVisibleDuration(clip)); // Returns seconds with millisecond precision

```

### Configuring Snap Behavior

To enable snapping to whole-millisecond intervals during UI interactions:

```typescript
import { useTimelineStore } from '@/store/timelineStore';

// Toggle snap to 0.001s (1ms) grid
useTimelineStore.getState().toggleSnapEnabled();

```

## UI Precision and Zoom Handling

The visual representation of millisecond-level changes depends on the timeline's zoom level, calculated in [`src/lib/timeline/timelineZoom.ts`](https://github.com/AIEraDev/Clypra/blob/main/src/lib/timeline/timelineZoom.ts). The `pixelsPerSecond` value determines how many pixels represent one second of time. When zoomed in sufficiently, a single millisecond change (0.001 seconds) becomes visually apparent as a one-pixel shift or greater.

For display purposes, [`src/lib/utils/timeFormatting.ts`](https://github.com/AIEraDev/Clypra/blob/main/src/lib/utils/timeFormatting.ts) (lines 52-53) provides utilities that format timestamps with millisecond precision, ensuring that the user interface reflects the exact values stored in the `trimIn` and `trimOut` fields.

## Summary

- **Storage Format**: Clypra uses floating-point seconds (`0.001` = 1ms) for all timing values, defined in [`src/types/index.ts`](https://github.com/AIEraDev/Clypra/blob/main/src/types/index.ts)
- **Core Helpers**: `normalizeClipTiming` and `getClipVisibleDuration` in [`timelineClip.ts`](https://github.com/AIEraDev/Clypra/blob/main/timelineClip.ts) enforce the invariant that `duration === trimOut - trimIn`
- **Ripple Editing**: The `rippleTrimClip` method in [`timelineStore.ts`](https://github.com/AIEraDev/Clypra/blob/main/timelineStore.ts) (lines 857-910) maintains millisecond accuracy when shifting downstream clips
- **Manual Updates**: Use `updateClip` from the timeline store to programmatically set `trimIn` and `trimOut` to exact millisecond values
- **Visual Feedback**: `pixelsPerSecond` zoom ratios and `snapGuides` enable precise UI interaction at the millisecond level

## Frequently Asked Questions

### What data type does Clypra use for millisecond-accurate timing?

Clypra stores all timing values as JavaScript `number` types (IEEE-754 double-precision floating-point), representing time in seconds. This allows millisecond precision by using values like `0.001` for one millisecond, providing sufficient accuracy for sub-frame editing without requiring specialized rational number libraries.

### How does Clypra prevent trim values from exceeding the source media duration?

The `normalizeClipTiming` function in [`src/lib/timeline/timelineClip.ts`](https://github.com/AIEraDev/Clypra/blob/main/src/lib/timeline/timelineClip.ts) clamps both `trimIn` and `trimOut` using `Math.max(0, Math.min(trim, sourceDuration))`. This ensures trim points never fall below zero or exceed the actual source length, maintaining valid clip boundaries even when users drag trim handles aggressively or programmatic updates provide invalid values.

### What is the difference between a standard trim and a ripple trim in Clypra?

A standard trim modifies only the target clip's `trimIn` or `trimOut` values without affecting other clips. A ripple trim, implemented via `rippleTrimClip` in [`src/store/timelineStore.ts`](https://github.com/AIEraDev/Clypra/blob/main/src/store/timelineStore.ts), adjusts the trim point and then propagates the time change (`deltaTime`) to all subsequent clips on the same track. This shifts downstream content to prevent gaps or overlaps while maintaining the exact millisecond duration change specified.

### How does the timeline UI handle millisecond-precision trimming when zoomed out?

The UI relies on the `pixelsPerSecond` zoom ratio defined in [`src/lib/timeline/timelineZoom.ts`](https://github.com/AIEraDev/Clypra/blob/main/src/lib/timeline/timelineZoom.ts). At low zoom levels, milliseconds may occupy less than one pixel, making them visually imperceptible but still stored accurately. When users enable snapping via `toggleSnapEnabled()`, the UI constrains drag operations to whole-millisecond intervals (0.001s), ensuring precise edits regardless of the current zoom level.