A linear binder has free N- and C-termini. It is what stock BindCraft produces. A cyclic binder has its N(1) and C(L) residues joined by a peptide (amide) bond, forming a closed ring. Cyclic binders are more protease-resistant, more orally bioavailable, and pay a smaller entropic penalty on binding. The trade-off is synthesis cost (one extra cyclization step) and a length ceiling (~60 aa for clean head-to-tail cyclization).
FAQ
Frequently asked questions.
Twenty-two questions covering general, technical, performance, synthesis, and licensing topics. Filter by category or scan the full list.
RFpeptide (Rettie et al., Nat. Chem. Biol. 2025) runs on top of RFdiffusion and requires SE(3)-Transformer, e3nn, OpenFold weights, and ~12 GB of additional dependencies. Cyclic BindCraft reuses the AF2 backbone you already have installed (via ColabDesign), ports RFpeptide's ~50-line cyclization encoding, and adds a constrained FastRelax + cyclic-aware filters. The result is a much smaller dependency footprint, faster iteration, and the ability to keep using your existing BindCraft config files for linear designs. The trade-off is that AF2's structure module still sees a linear sequence during its iteration (see Q14), so for production-critical designs we recommend a second-pass validation with AfCycDesign or RF2-cyclic.
Not directly. AF2 and ProteinMPNN were trained on L-amino-acid backbones, so their predictions on D-backbones are unreliable. To use D-amino acids, you would need to (a) install a D-enabled PyRosetta scorefunction, (b) flip the Cα coordinates of selected residues after design, and (c) accept that AF2's pLDDT will not reflect true structural confidence. We recommend designing an L-binder first, then experimentally substituting D-residues at protease-sensitive positions after synthesis.
Not currently. The cyclic patch supports a single head-to-tail bond per binder chain. Bicyclic designs (e.g. a head-to-tail ring + an internal disulfide) would require two DeclareBond calls and two cyclize_relpos wraps. This is on the future-work list.
The most common reasons:
cyclic_NC_distance > 1.5 Å— FastRelax failed to close the ring. Raiseweights_cyclic_bond_lossto 1.5–2.0 inpeptide_cyclic_3stage.json, or raiseweights_termini_lossto 1.0.cyclic_omegaoutside [150°, 210°] — the closing amide bond is cis or distorted. Lowertarget_omegatolerance to ±15°, or increase the dihedral constraint weight inpr_relax_cyclic.Average_i_pTM < 0.45— AF2 is not confident the binder docks. Lower the threshold to 0.40 inpeptide_cyclic_filters.json, or pick a different hotspot set.Average_dG > -25 kcal/mol— Rosetta thinks the interface is weak. Increasenum_seqs(MPNN sampling) to 30, or relaxmpnn_fix_interfacetofalseto redesign the interface too.Average_Binder_RMSD > 2.0 Å— the binder doesn't fold into the same structure when re-predicted alone. The cyclic encoding may be insufficient for your binder length; try a shorterlengthsrange.
Minimum 16 GB VRAM (e.g. RTX 3090, T4) for binders ≤45 aa against a 200-residue target. Recommended ≥24 GB (A100, A6000, RTX 4090, H100) for binders up to 55 aa against a 400-residue target. CPU-only is impractical (a single trajectory takes ~6 hours on a 32-core CPU vs. ~3 minutes on an A100).
~3 minutes per trajectory on a single A100. For number_of_final_designs: 50 with a typical acceptance rate of ~20%, expect ~250 trajectories = ~12.5 hours total. For the PD-L1 example in the Tutorial, the smaller lengths: [25, 45] and number_of_final_designs: 50 completes in ~4 hours.
Technically yes (pip install jax[cpu]), but practically no. A single trajectory takes ~6 hours on a 32-core CPU. The cyclic patch is GPU-only by design — check_jax_gpu() exits if no GPU is found, matching stock BindCraft.
See Citation & License. In brief: cite Pacesa et al. for BindCraft, Rettie et al. for RFpeptide, and (placeholder) this Cyclic BindCraft modification. A citation.bib is included in the repo root.
The cyclic patch enforces a soft cap of 60 residues for cyclic mode. Beyond 60, the cyclic relative-position encoding becomes less informative (the "shortest path around the ring" assumption weakens), and AF2's structure module struggles to fold the long ring. For binders >60 aa, use stock BindCraft with default_4stage_multimer.json (linear).
Yes, but it requires two changes: (a) remove C from omit_AAs in the advanced JSON (so MPNN can sample Cys); (b) after the head-to-tail cyclization in pr_relax_cyclic, add a second DeclareBond between the two Cys sulfur atoms. The cyclic patch does not currently support this automatically — you would need to call pr_relax_cyclic with a custom patch. This is on the future-work list.
Not currently. BindCraft's hallucination pipeline relies on ColabDesign's differentiable AF2 (JAX-based, supports backprop). AlphaFold3 (as released by Google DeepMind / AlphaFold Server) is not differentiable in the same way and does not expose the structure-module callbacks BindCraft uses. If a differentiable AF3 implementation becomes available, the cyclic relpos trick should port directly (the same 2D positional encoding exists in AF3's PairFormer).
It is the distance in Å between the binder's N(1) atom and C(L) atom in the final relaxed PDB. A true cyclic amide bond has N–C ≈ 1.33 Å. The filter threshold is 1.5 Å (a small tolerance for FastRelax's numerical noise). Values >2.0 Å indicate FastRelax failed to close the ring — reject the design. Values 1.5–2.0 Å are marginal — re-relax with a higher weights_cyclic_bond_loss.
AF2's structure module iterates over residues in their linear order (1, 2, 3, …, L). The cyclic relpos patch modifies the pairwise embedding (the 2-D relpos tensor and the bonded-neighbor feature) but not the iteration order. So during each structure-module iteration, AF2 sees residue L as the last item in the sequence, not as the predecessor of residue 1. This is a known limitation (see Cyclization Science §8.1). In practice the cyclic bond loss + cyclic relpos is sufficient to drive the binder into a cyclic geometry — the chain break is invisible in the final coordinates. For maximum fidelity, validate with AfCycDesign.
Standard Fmoc SPPS on 2-chlorotrityl chloride resin (cleaves the C-terminus as a free acid) → cleave from resin with 1% TFA in DCM (preserves sidechain protecting groups) → cyclize in dilute solution (1 mM peptide in DMF) with PyAOP/DIEA (1.5 eq, 2–4 h, RT) → global deprotection with TFA/TIS/water 95/2.5/2.5 for 2 h → purify by RP-HPLC → confirm by MALDI-TOF. See Tutorial step 9.
Not in a single bindcraft.py invocation. The simplest multi-GPU strategy is to launch N independent processes, each pinned to one GPU with CUDA_VISIBLE_DEVICES, each with a different random seed (or different hotspot subset). The output directories can then be merged. A SLURM array job template is provided in bindcraft.slurm (one task per GPU).
Edit weights_cyclic_bond_loss in settings_advanced/peptide_cyclic_3stage.json. Default 0.5. Range 0.1 (loose) to 2.0 (very tight). If your trajectories consistently fail to close the ring, raise to 1.0–2.0. If FastRelax takes too long (max_iter hits), lower to 0.3–0.5 and rely on the constrained FastRelax to finish the job.
You cannot run Cyclic BindCraft without PyRosetta — the constrained FastRelax (Stage 3) and the InterfaceAnalyzerMover scoring (Stage 5) are essential. PyRosetta is free for academic and non-commercial use; register at els2.comotion.uw.edu/product/pyrosetta. For commercial use, a Rosetta commercial license is required.
If you absolutely cannot install PyRosetta, the alternative is to use ESMFold + a custom relaxation script, but the result quality will be substantially worse and the cyclic_NC_distance / cyclic_omega filters will not be enforceable.
Apply the cyclic patch:
cd ~/cyclic-bindcraft/repo
git fetch && git checkout v1.5.3 # pin to the version the patch is built against
git apply /path/to/cyclic.patch
python -c "from functions.cyclic_utils import cyclize_relpos; print('OK')"
Your existing default_filters.json and default_4stage_multimer.json continue to work for linear designs. The patch only adds code; nothing is removed. See Installation §"Updating from stock BindCraft".
For Cyclic BindCraft-specific bugs (cyclization encoding, constrained relax, cyclic filters, JSON preset issues): open an issue on the Cyclic BindCraft repository (link TBD; the patch will ship with a CONTRIBUTING.md that lists the issue tracker).
For stock BindCraft bugs (AF2 hallucination, MPNN sampling, Rosetta scoring, CSV writing): open an issue on github.com/martinpacesa/BindCraft/issues.
For PyRosetta bugs: github.com/RosettaCommons/PyRosetta_bug_reports.
When filing a bug, please include: (1) the exact command line, (2) the three JSON config files, (3) the full stderr output (especially any PyRosetta traceback), (4) the first 10 lines of failure_csv.csv, and (5) the output of python -c "import jax, pyrosetta; print(jax.__version__, pyrosetta.__version__)".
Yes, as long as they are AF2-multimer-compatible (same architecture as params_model_1_multimer.npz … params_model_5_multimer.npz). Set af_params_dir in your advanced JSON to the directory containing your weights. The cyclic relpos patch is independent of the weights — it modifies only the input features, not the network parameters.
Most modern tools (PyMOL, ChimeraX, BioPython, MDAnalysis) parse CONECT records natively. If your tool doesn't, you can safely strip the CONECT line — the cyclic topology is preserved geometrically (N(1) and C(L) are within 1.33 Å). Use clean_pdb (the stock version) to strip both CONECT and REMARK 470 if needed:
from functions.generic_utils import clean_pdb
clean_pdb('Accepted/my_design.pdb') # strips CONECT, REMARK 470
Note: after stripping, the cyclic_NC_distance filter will still pass (it reads coordinates, not CONECT), but pr_relax_cyclic will not be able to re-relate the pose if you re-run it on the stripped file.