『日本書紀』天武天皇9年（680年）11月12日条には、天武天皇が後の持統天皇である鵜野讃良（うののさらら）皇后の病気平癒を祈願して薬師寺の建立を発願し、百僧を得度（出家）させたとある。薬師寺東塔の屋上にある相輪支柱に刻まれた「東塔檫銘」（とうとうさつめい、「さつ」は木偏に「察」）にも同趣旨の記述がある。しかし、天武天皇は寺の完成を見ずに朱鳥元年（686年）没し、伽藍整備は持統天皇、文武天皇の代に引き継がれた。「東塔檫銘」には、「清原宮に天の下を統治した天皇（天武）の即位八年、庚辰の歳、中宮（後の持統天皇）の病気のため、この伽藍を創り始めたが、完成しないうちに崩御したので、その意志を継いで、太上天皇（持統）が完成したものである」という意味のことが記されている。ここでいう「天皇即位八年、庚辰之歳」は、『書紀』の「天武天皇9年」と同じ年を指している。すなわち、『書紀』は天智天皇の没した翌年（壬申年、西暦672年にあたる）を天武天皇元年とするが、天武が正式に即位したのはその翌年（西暦673年にあたる）であり、「天皇即位八年」とは即位の年から数えて8年目という意味である。持統天皇2年（688年）、薬師寺にて無遮大会（かぎりなきおがみ）という行事が行われたことが『書紀』に見え、この頃までにはある程度伽藍が整っていたものと思われる。『続日本紀』によれば、文武天皇2年（698年）には寺の造営がほぼ完成し、僧を住まわせている。この創建薬師寺は、藤原京の右京八条三坊の地にあった。大和三山の畝傍山と香久山の中間にあたる橿原市城殿町に寺跡が残り、「本薬師寺（もとやくしじ）跡」として特別史跡に指定されている。
薬師寺は天武天皇9年（680年）、天武天皇の発願により、飛鳥の藤原京（奈良県橿原市城殿〈きどの〉町）の地に造営が開始され、平城遷都後の8世紀初めに現在地の西ノ京に移転したものである。ただし、飛鳥の薬師寺（本薬師寺、北緯34度29分33.88秒東経135度48分0.95秒）の伽藍も10世紀頃までは引き続き存続していたと見られる。
Groovyで実装を説明する。まず、符号情報とハフマン木のクラスを作る。class CodeInfo { int code, codeSize }class TreeNode implements Comparable<TreeNode> {  byte value; int occurrence; List<TreeNode> children;  int compareTo(TreeNode that) { this.occurrence - that.occurrence }}すると、バイト値→符号情報のテーブルは以下のようにして作れる。CodeInfo[] createValue2Code(byte[] data) {  // 各バイト値の発生回数を数える  TreeNode[] nodes = new TreeNode[256]  for (int i in 0..<256) { nodes[i] = new TreeNode(value: i) }  for (byte v in data) { nodes[v].occurrence++ }  // ハフマン木を作成  PriorityQueue<TreeNode> queue = new PriorityQueue<TreeNode>(nodes as List)  while (queue.size() > 1) {    TreeNode n1 = queue.poll(), n2 = queue.poll()    queue << new TreeNode(occurrence: n1.occurrence + n2.occurrence, children: [n1, n2])  }  TreeNode root = queue.poll()  // 深さ優先探索でバイト値→符号情報を作成  CodeInfo[] value2code = new CodeInfo[256]  dfs(value2code, root, 0, 0)  return value2code}void dfs(CodeInfo[] value2code, TreeNode node, int code, int codeSize) {  if (node.children == null) {    value2code[node.value] = new CodeInfo(code: code, codeSize: codeSize)  } else {    dfs(value2code, node.children[0], code << 1, codeSize + 1)    dfs(value2code, node.children[1], (code << 1) + 1, codeSize + 1)  }}圧縮のために以下のようなビットストリームのクラスを作る。class BitStream {  BitSet bs = new BitSet(); int len = 0, pos = 0;  void write(int v, int bits) {    for (int i in 0..<bits) { bs[len++] = ((v >>> i) & 1) != 0 }  }  int read(int bits) {    int v = 0; for (int i in 0..<bits) { if (bs[pos++]) { v |= 1 << i } }    return v  }  String toString() { "length = $len, {" + (0..<len).findAll({ bs[it] }).join(", ") + "}" }}すると、バイト値→符号情報のテーブルを使い以下のようにして圧縮できる。void compress(BitStream bs, byte[] data, CodeInfo[] value2code) {  for (byte v in data) {    CodeInfo codeInfo = value2code[v]    bs.write(codeInfo.code, codeInfo.codeSize)  }}