Tessera: Seamless, endlessly tileable SwiftUI patterns

Hey,

I’ve been working on a Swift package called Tessera.

The idea is pretty simple:

  • You describe a set of items as regular SwiftUI views (SF Symbols, shapes, your own custom views, etc.).
  • Tessera generates a single tile from those items.
  • The tile’s edges wrap toroidally, so the result repeats without seams.
  • You can either repeat that tile to fill any space, or render a finite “one-off” canvas at a specific size.
  • If you want to export assets, there are helpers to render PNG or vector-friendly PDF.

This is meant to be a pragmatic “pattern engine” you can drop into an app for backgrounds, posters, cards, wallpapers, etc.

Example 1: An endlessly repeating background

TesseraTiledCanvas generates one tile (based on tileSize), caches it as a Canvas symbol, and repeats it to fill the available space.

import SwiftUI
import Tessera

struct PatternBackground: View {
  var body: some View {
    TesseraTiledCanvas(
      configuration,
      tileSize: CGSize(width: 256, height: 256),
      seed: 20
    )
    .ignoresSafeArea()
  }

  var configuration: TesseraConfiguration {
    TesseraConfiguration(
      items: items,
      minimumSpacing: 10,
      density: 0.6,
      baseScaleRange: 0.9...1.15
    )
  }

  var items: [TesseraItem] {
    [
      TesseraItem(approximateSize: CGSize(width: 30, height: 30)) {
        Image(systemName: "sparkle")
          .font(.system(size: 24, weight: .semibold))
          .foregroundStyle(.primary.opacity(0.9))
      },
      TesseraItem(approximateSize: CGSize(width: 30, height: 30)) {
        Image(systemName: "circle.grid.cross")
          .font(.system(size: 24, weight: .semibold))
          .foregroundStyle(.primary.opacity(0.7))
      },
      TesseraItem(
        weight: 0.5,
        allowedRotationRange: .degrees(-15)

Example 2: A finite canvas

If you want a single generated composition (for UI or export), use TesseraCanvas and give it a frame.

import SwiftUI
import Tessera

struct Poster: View {
  var body: some View {
    TesseraCanvas(configuration, edgeBehavior: .finite)
      .frame(width: 600, height: 400)
  }

  var configuration: TesseraConfiguration {
    TesseraConfiguration(items: items, minimumSpacing: 10, density: 0.65)
  }

  var items: [TesseraItem] {
    [
      TesseraItem(approximateSize: CGSize(width: 34, height: 34)) {
        Image(systemName: "scribble.variable")
          .font(.system(size: 28, weight: .semibold))
          .foregroundStyle(.primary.opacity(0.8))
      }
    ]
  }
}

Pinned items

You can pin items to specific positions on the canvas, and Tessera will fill in the space around them. Pinned items participate in collision checks, so generated items keep their distance.

import SwiftUI
import Tessera

struct HeroCard: View {
  var body: some View {
    TesseraCanvas(
      configuration,
      fixedItems: [logo],
      edgeBehavior: .finite
    )
    .frame(width: 600, height: 360)
    .clipShape(RoundedRectangle(cornerRadius: 24, style: .continuous))
  }

  var configuration: TesseraConfiguration {
    TesseraConfiguration(items: items, minimumSpacing: 10, density: 0.7)
  }

  var items: [TesseraItem] {
    [
      TesseraItem(approximateSize: CGSize(width: 28, height: 28)) {
        Image(systemName: "hexagon.fill")
          .font(.system(size: 22, weight: .bold))
          .foregroundStyle(.blue.opacity(0.55))
      }
    ]
  }

  var logo: TesseraFixedItem {
    TesseraFixedItem(
      position: .centered(),
      approximateSize: CGSize(width: 160, height: 160)
    ) {
      Image(systemName: "t.square.fill")
        .font(.system(size: 120, weight: .heavy))
        .foregroundStyle(.primary)
    }
  }
}

Exporting PNG / PDF

For exports, you can render a tile directly.

import Foundation
import SwiftUI
import Tessera

let configuration = TesseraConfiguration(
  items: items,
  seed: 0,
  minimumSpacing: 10,
  density: 0.8,
  baseScaleRange: 0.5...1.2
)

let tile = TesseraTile(configuration, tileSize: CGSize(width: 256, height: 256))
let outputDir = FileManager.default.temporaryDirectory

// PNG at an exact pixel size (scale is derived automatically)
let pngURL = try tile.renderPNG(
  to: outputDir,
  fileName: "tessera",
  options: .init(targetPixelSize: CGSize(width: 2000, height: 2000))
)

// Vector-friendly PDF (page size is in points)
let pdfURL = try tile.renderPDF(
  to: outputDir,
  fileName: "tessera",
  pageSize: CGSize(width: 256, height: 256)
)

A few practical notes

  • Tessera uses Canvas symbols for performance, so keeping item views lightweight helps a lot.
  • Collision geometry is intentionally conservative when you only provide an approximateSize . If an item has a weird footprint, you can provide a more accurate collisionShape .
  • There’s a maximumItemCount safety cap — if you crank density on large canvases, you may want to raise it.

Repo

15 Likes