diff --git a/graphql_query_derive/Cargo.toml b/graphql_query_derive/Cargo.toml
index 11f6e6fd..258884c6 100644
--- a/graphql_query_derive/Cargo.toml
+++ b/graphql_query_derive/Cargo.toml
@@ -11,6 +11,7 @@ edition = "2018"
 proc-macro = true
 
 [dependencies]
+shellexpand = "^3.1"
 syn = { version = "^1.0", features = ["extra-traits"] }
 proc-macro2 = { version = "^1.0", features = [] }
 graphql_client_codegen = { path = "../graphql_client_codegen/", version = "0.14.0" }
diff --git a/graphql_query_derive/src/attributes.rs b/graphql_query_derive/src/attributes.rs
index e9d31e14..556c2152 100644
--- a/graphql_query_derive/src/attributes.rs
+++ b/graphql_query_derive/src/attributes.rs
@@ -37,22 +37,22 @@ pub fn ident_exists(ast: &syn::DeriveInput, ident: &str) -> Result<(), syn::Erro
     ))
 }
 
-/// Extract an configuration parameter specified in the `graphql` attribute.
-pub fn extract_attr(ast: &syn::DeriveInput, attr: &str) -> Result<String, syn::Error> {
+/// Extract a literal string configuration parameter specified in the `graphql` attribute.
+pub fn extract_attr_literal(ast: &syn::DeriveInput, attr: &str) -> Result<syn::LitStr, syn::Error> {
     let attributes = &ast.attrs;
     let graphql_path = path_to_match();
     let attribute = attributes
         .iter()
         .find(|attr| attr.path == graphql_path)
         .ok_or_else(|| syn::Error::new_spanned(ast, "The graphql attribute is missing"))?;
-    if let syn::Meta::List(items) = &attribute.parse_meta().expect("Attribute is well formatted") {
-        for item in items.nested.iter() {
+    if let syn::Meta::List(items) = attribute.parse_meta().expect("Attribute is well formatted") {
+        for item in items.nested.into_iter() {
             if let syn::NestedMeta::Meta(syn::Meta::NameValue(name_value)) = item {
                 let syn::MetaNameValue { path, lit, .. } = name_value;
                 if let Some(ident) = path.get_ident() {
                     if ident == attr {
                         if let syn::Lit::Str(lit) = lit {
-                            return Ok(lit.value());
+                            return Ok(lit);
                         }
                     }
                 }
@@ -66,6 +66,11 @@ pub fn extract_attr(ast: &syn::DeriveInput, attr: &str) -> Result<String, syn::E
     ))
 }
 
+/// Extract an configuration parameter specified in the `graphql` attribute.
+pub fn extract_attr(ast: &syn::DeriveInput, attr: &str) -> Result<String, syn::Error> {
+    extract_attr_literal(ast, attr).map(|lit| lit.value())
+}
+
 /// Extract a list of configuration parameter values specified in the `graphql` attribute.
 pub fn extract_attr_list(ast: &syn::DeriveInput, attr: &str) -> Result<Vec<String>, syn::Error> {
     let attributes = &ast.attrs;
diff --git a/graphql_query_derive/src/lib.rs b/graphql_query_derive/src/lib.rs
index f335aa79..e5bbf02d 100644
--- a/graphql_query_derive/src/lib.rs
+++ b/graphql_query_derive/src/lib.rs
@@ -47,10 +47,18 @@ fn build_query_and_schema_path(input: &syn::DeriveInput) -> Result<(PathBuf, Pat
         )
     })?;
 
-    let query_path = attributes::extract_attr(input, "query_path")?;
+    fn extract_and_expand_attr(input: &syn::DeriveInput, attr: &str) -> Result<String, syn::Error> {
+        let literal = attributes::extract_attr_literal(input, attr)?;
+
+        shellexpand::env(&literal.value())
+            .map(std::borrow::Cow::into_owned)
+            .map_err(|err| syn::Error::new_spanned(literal, err))
+    }
+
+    let query_path = extract_and_expand_attr(input, "query_path")?;
     let query_path = format!("{}/{}", cargo_manifest_dir, query_path);
     let query_path = Path::new(&query_path).to_path_buf();
-    let schema_path = attributes::extract_attr(input, "schema_path")?;
+    let schema_path = extract_and_expand_attr(input, "schema_path")?;
     let schema_path = Path::new(&cargo_manifest_dir).join(schema_path);
     Ok((query_path, schema_path))
 }