diff --git a/package-lock.json b/package-lock.json
index 6c89b0f359c83badbc08f0ea4223fd151c4475cc..e79e6e264ae78f3a1bc547133c07fb54afdc54c2 100644
Binary files a/package-lock.json and b/package-lock.json differ
diff --git a/src/mol-io/writer/cif.ts b/src/mol-io/writer/cif.ts
index c191d8a4bdeca25d9c377abe354980931bcad2f3..762f1988f1868b0c4d1e58f48b86ad06c6f5fd47 100644
--- a/src/mol-io/writer/cif.ts
+++ b/src/mol-io/writer/cif.ts
@@ -53,5 +53,58 @@ export namespace CifWriter {
                 return ff && ff.binaryEncoding ? ArrayEncoder.fromEncoding(ff.binaryEncoding) : void 0;
             }
         }
+    };
+
+    export function createEncodingProviderFromJsonConfig(hints: EncodingStrategyHint[]): EncodingProvider {
+        return {
+            get(c, f) {
+                for (let i = 0; i < hints.length; i++) {
+                    const hint = hints[i];
+                    if (hint.categoryName === c && hint.columnName === f) {
+                        return resolveEncoding(hint);
+                    }
+                }
+            }
+        }
     }
+
+    function resolveEncoding(hint: EncodingStrategyHint): ArrayEncoder | undefined {
+        const precision: number | undefined = hint.precision;
+        if (precision !== void 0) {
+            const multiplier = Math.pow(10, precision);
+            const fixedPoint = E.by(E.fixedPoint(multiplier));
+            switch (hint.encoding) {
+                case 'pack':
+                    return fixedPoint.and(E.integerPacking);
+                case 'rle':
+                    return fixedPoint.and(E.runLength).and(E.integerPacking);
+                case 'delta':
+                    return fixedPoint.and(E.delta).and(E.integerPacking);
+                case 'delta-rle':
+                    return fixedPoint.and(E.delta).and(E.runLength).and(E.integerPacking);
+            };
+        } else {
+            switch (hint.encoding) {
+                case 'pack':
+                    return E.by(E.integerPacking);
+                case 'rle':
+                    return E.by(E.runLength).and(E.integerPacking);
+                case 'delta':
+                    return E.by(E.delta).and(E.integerPacking);
+                case 'delta-rle':
+                    return E.by(E.delta).and(E.runLength).and(E.integerPacking);
+            }
+        }
+    }
+}
+
+// defines the information needed to encode certain fields: category and column name as well as encoding tag, precision is optional and identifies float columns
+// TODO would be nice to infer strategy and precision if needed
+export interface EncodingStrategyHint {
+    categoryName: string,
+    columnName: string,
+    // 'pack', 'rle', 'delta', or 'delta-rle'
+    encoding: string,
+    // number of decimal places to keep - must be specified to float columns
+    precision?: number
 }
\ No newline at end of file
diff --git a/src/mol-io/writer/cif/encoder/binary.ts b/src/mol-io/writer/cif/encoder/binary.ts
index 9212bcea20d8862792026f96bee41745517b59b4..99ee5005375852ddd38feb594f18d2a8071a9358 100644
--- a/src/mol-io/writer/cif/encoder/binary.ts
+++ b/src/mol-io/writer/cif/encoder/binary.ts
@@ -111,12 +111,13 @@ function getDefaultEncoder(type: Field.Type): ArrayEncoder {
 }
 
 function tryGetEncoder(categoryName: string, field: Field, format: Field.Format | undefined, provider: EncodingProvider | undefined) {
-    if (format && format.encoder) {
+    // TODO made provider the first check - might break servers/model/query
+    if (provider && provider.get(categoryName, field.name)) {
+        return provider.get(categoryName, field.name);
+    } else if (format && format.encoder) {
         return format.encoder;
     } else if (field.defaultFormat && field.defaultFormat.encoder) {
         return field.defaultFormat.encoder;
-    } else if (provider) {
-        return provider.get(categoryName, field.name);
     } else {
         return void 0;
     }
diff --git a/src/tests/browser/encoding-config.ts b/src/tests/browser/encoding-config.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b02ed4ea8481a41b2e66095b427d994eb9c7ecaf
--- /dev/null
+++ b/src/tests/browser/encoding-config.ts
@@ -0,0 +1,91 @@
+import './index.html'
+import { CIF, CifCategory, CifField, getCifFieldType } from '../../mol-io/reader/cif';
+import { CifWriter } from '../../mol-io/writer/cif';
+import { classifyFloatArray, classifyIntArray } from '../../mol-io/common/binary-cif';
+
+async function parseCif(data: string|Uint8Array) {
+    const comp = CIF.parse(data);
+    const parsed = await comp.run();
+    if (parsed.isError) throw parsed;
+    return parsed.result;
+}
+
+async function downloadCif(url: string, isBinary: boolean) {
+    const data = await fetch(url);
+    return parseCif(isBinary ? new Uint8Array(await data.arrayBuffer()) : await data.text());
+}
+
+async function downloadFromPdb(pdb: string) {
+    const parsed = await downloadCif(`https://webchem.ncbr.muni.cz/ModelServer/static/bcif/${pdb}`, true);
+    return parsed.blocks[0];
+}
+
+async function init(props = {}) {
+    const cif = await downloadFromPdb('1brr')
+    const encoder = CifWriter.createEncoder({
+        binary: true,
+        encoderName: 'mol*',
+        binaryEncodingPovider: CifWriter.createEncodingProviderFromJsonConfig([
+            {
+                'categoryName': 'atom_site',
+                'columnName': 'Cartn_y',
+                'encoding': 'rle',
+                'precision': 0
+            },
+            {
+                'categoryName': 'atom_site',
+                'columnName': 'Cartn_z',
+                'encoding': 'delta',
+                'precision': 1
+            },
+            {
+                'categoryName': 'atom_site',
+                'columnName': 'label_seq_id',
+                'encoding': 'delta-rle'
+            }
+        ])
+    });
+
+    encoder.startDataBlock(cif.header);
+    for (const c of cif.categoryNames) {
+        const cat = cif.categories[c];
+        const fields: CifWriter.Field[] = [];
+        for (const f of cat.fieldNames) {
+            fields.push(classify(f, cat.getField(f)!))
+        }
+
+        encoder.writeCategory(getCategoryInstanceProvider(cif.categories[c], fields));
+    }
+    const ret = encoder.getData() as Uint8Array;
+
+    const cif2 = (await parseCif(ret)).blocks[0];
+    // should be untouched
+    console.log(cif2.categories['atom_site'].getField('Cartn_x'));
+    // should have integer precision
+    console.log(cif2.categories['atom_site'].getField('Cartn_y'));
+    // should have 1 decimal place
+    console.log(cif2.categories['atom_site'].getField('Cartn_z'));
+    console.log(cif2.categories['atom_site'].getField('label_seq_id'));
+}
+
+init()
+
+function getCategoryInstanceProvider(cat: CifCategory, fields: CifWriter.Field[]): CifWriter.Category {
+    return {
+        name: cat.name,
+        instance: () => CifWriter.categoryInstance(fields, { data: cat, rowCount: cat.rowCount })
+    };
+}
+
+function classify(name: string, field: CifField): CifWriter.Field {
+    const type = getCifFieldType(field);
+    if (type['@type'] === 'str') {
+        return { name, type: CifWriter.Field.Type.Str, value: field.str, valueKind: field.valueKind };
+    } else if (type['@type'] === 'float') {
+        const encoder = classifyFloatArray(field.toFloatArray({ array: Float64Array }));
+        return CifWriter.Field.float(name, field.float, { valueKind: field.valueKind, encoder, typedArray: Float64Array });
+    } else {
+        const encoder = classifyIntArray(field.toIntArray({ array: Int32Array }));
+        return CifWriter.Field.int(name, field.int, { valueKind: field.valueKind, encoder, typedArray: Int32Array });
+    }
+}
\ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
index 3de9e1565111c706a5f326ff84f7f9f143cc4e28..c171386df79f848f39afbbc8d22abdbcc0666a77 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -98,4 +98,5 @@ module.exports = [
     createBrowserTest('render-spheres'),
     createBrowserTest('render-structure'),
     createBrowserTest('render-text'),
+    createBrowserTest('encoding-config')
 ]
\ No newline at end of file