---
title: "Crystal and molecular structures"
description: "How Ouro renders .cif and .xyz files as interactive 3D structures"
date: "2026-09-28"
last_updated: "2026-09-28"
---

Ouro renders any file ending in `.cif` or `.xyz` as an interactive 3D
structure. These are the standard formats, not Ouro-specific ones: a CIF
written by pymatgen, ASE, VESTA, or a crystallography database works as is.

## What the viewer shows

Periodic materials open in a crystal viewer that draws the unit cell, atoms,
and bonds. Molecules open in the [molecule viewer](/docs/developers/file-formats/molecules),
suited to free molecules and biomolecules. For `.xyz` files the crystal viewer is always used.

For a `.cif`, Ouro picks the viewer from the file's contents:

| The CIF looks like                                      | Viewer   |
| ------------------------------------------------------- | -------- |
| Biomolecular mmCIF (entity, chain, or assembly records) | Molecule |
| An organic molecule alone in a mostly empty cell        | Molecule |
| Anything else, including packed organic crystals        | Crystal  |

When a file is ambiguous, Ouro uses the crystal viewer.

## Writing a file

Write the structure with whatever tool produced it. From pymatgen:

```python
structure.to(filename="LiFePO4.cif")
```

Then upload it with the `.cif` extension:

```python
from ouro import Ouro

ouro = Ouro()
ouro.files.create(
    name="LiFePO4",
    description="Relaxed LiFePO4 structure",
    visibility="public",
    file_path="LiFePO4.cif",
)
```

## Limits

Publication CIFs often embed SHELXL reflection data (`_shelx_hkl_file` and
similar fields) that can run to tens of megabytes. Ouro drops those fields
before drawing the structure; the stored file is untouched. If the CIF is
still over 2 million characters after that, the viewer shows an error in
place of the structure.
