diff --git a/core/commands2/add.go b/core/commands2/add.go
index 52893797bea629e55029250f83f117a89e89cd35..8bd60da95fdbb944beadc4180c461c60b37dc6a9 100644
--- a/core/commands2/add.go
+++ b/core/commands2/add.go
@@ -5,6 +5,7 @@ import (
 	"errors"
 	"fmt"
 	"io"
+	"strings"
 
 	cmds "github.com/jbenet/go-ipfs/commands"
 	core "github.com/jbenet/go-ipfs/core"
@@ -12,6 +13,7 @@ import (
 	"github.com/jbenet/go-ipfs/importer/chunk"
 	dag "github.com/jbenet/go-ipfs/merkledag"
 	pinning "github.com/jbenet/go-ipfs/pin"
+	ft "github.com/jbenet/go-ipfs/unixfs"
 	u "github.com/jbenet/go-ipfs/util"
 )
 
@@ -34,11 +36,8 @@ remains to be implemented.
 `,
 	},
 
-	Options: []cmds.Option{
-		cmds.BoolOption("recursive", "r", "Must be specified when adding directories"),
-	},
 	Arguments: []cmds.Argument{
-		cmds.FileArg("path", true, true, "The path to a file to be added to IPFS"),
+		cmds.FileArg("path", true, true, "The path to a file to be added to IPFS").EnableRecursive(),
 	},
 	Run: func(req cmds.Request) (interface{}, error) {
 		added := &AddOutput{}
@@ -47,75 +46,22 @@ remains to be implemented.
 			return nil, err
 		}
 
-		_, _, err = req.Option("r").Bool()
-		if err != nil {
-			return nil, err
-		}
-
-		// returns the last one
-		addDagnode := func(name string, dn *dag.Node) error {
-			o, err := getOutput(dn)
-			if err != nil {
-				return err
-			}
-
-			added.Objects = append(added.Objects, o)
-			added.Names = append(added.Names, name)
-			return nil
-		}
-
-		addFile := func(file cmds.File) (*dag.Node, error) {
-			dns, err := add(n, []io.Reader{file})
-			if err != nil {
+		for {
+			file, err := req.Files().NextFile()
+			if err != nil && err != io.EOF {
 				return nil, err
 			}
-
-			log.Infof("adding file: %s", file.FileName())
-			if err := addDagnode(file.FileName(), dns[len(dns)-1]); err != nil {
-				return nil, err
+			if file == nil {
+				break
 			}
-			return dns[len(dns)-1], nil // last dag node is the file.
-		}
 
-		// TODO: handle directories
-
-		file, err := req.Files().NextFile()
-		for file != nil {
-			_, err := addFile(file)
+			_, err = addFile(n, file, added)
 			if err != nil {
 				return nil, err
 			}
-
-			file, err = req.Files().NextFile()
-		}
-		if err != nil && err != io.EOF {
-			return nil, err
 		}
 
 		return added, nil
-
-		// readers, err := internal.CastToReaders(req.Arguments())
-		// if err != nil {
-		// 	return nil, err
-		// }
-		//
-		// dagnodes, err := add(n, readers)
-		// if err != nil {
-		// 	return nil, err
-		// }
-		//
-		// // TODO: include fs paths in output (will need a way to specify paths in underlying filearg system)
-		// added := make([]*Object, 0, len(req.Arguments()))
-		// for _, dagnode := range dagnodes {
-		// 	object, err := getOutput(dagnode)
-		// 	if err != nil {
-		// 		return nil, err
-		// 	}
-		//
-		// 	added = append(added, object)
-		// }
-		//
-		// return &AddOutput{added}, nil
 	},
 	Marshalers: cmds.MarshalerMap{
 		cmds.Text: func(res cmds.Response) ([]byte, error) {
@@ -142,8 +88,6 @@ func add(n *core.IpfsNode, readers []io.Reader) ([]*dag.Node, error) {
 
 	dagnodes := make([]*dag.Node, 0)
 
-	// TODO: allow adding directories (will need support for multiple files in filearg system)
-
 	for _, reader := range readers {
 		node, err := importer.BuildDagFromReader(reader, n.DAG, mp, chunk.DefaultSplitter)
 		if err != nil {
@@ -168,3 +112,66 @@ func addNode(n *core.IpfsNode, node *dag.Node) error {
 
 	return nil
 }
+
+func addFile(n *core.IpfsNode, file cmds.File, added *AddOutput) (*dag.Node, error) {
+	if file.IsDirectory() {
+		return addDir(n, file, added)
+	}
+
+	dns, err := add(n, []io.Reader{file})
+	if err != nil {
+		return nil, err
+	}
+
+	log.Infof("adding file: %s", file.FileName())
+	if err := addDagnode(added, file.FileName(), dns[len(dns)-1]); err != nil {
+		return nil, err
+	}
+	return dns[len(dns)-1], nil // last dag node is the file.
+}
+
+func addDir(n *core.IpfsNode, dir cmds.File, added *AddOutput) (*dag.Node, error) {
+	log.Infof("adding directory: %s", dir.FileName())
+
+	tree := &dag.Node{Data: ft.FolderPBData()}
+
+	for {
+		file, err := dir.NextFile()
+		if err != nil && err != io.EOF {
+			return nil, err
+		}
+		if file == nil {
+			break
+		}
+
+		node, err := addFile(n, file, added)
+		if err != nil {
+			return nil, err
+		}
+
+		name := file.FileName()
+		slashIndex := strings.LastIndex(name, "/")
+		name = name[slashIndex+1:]
+
+		err = tree.AddNodeLink(name, node)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	addDagnode(added, dir.FileName(), tree)
+
+	return tree, addNode(n, tree)
+}
+
+// addDagnode adds dagnode info to an output object
+func addDagnode(output *AddOutput, name string, dn *dag.Node) error {
+	o, err := getOutput(dn)
+	if err != nil {
+		return err
+	}
+
+	output.Objects = append(output.Objects, o)
+	output.Names = append(output.Names, name)
+	return nil
+}